สร้างรายการของรายการเดียวซ้ำ N ครั้ง


523

ฉันต้องการสร้างชุดรายการความยาวผันแปรทั้งหมด แต่ละรายการจะมีองค์ประกอบเดียวกันeซ้ำnครั้ง (โดยที่n= ความยาวของรายการ)

ฉันจะสร้างรายการโดยไม่ต้องใช้ความเข้าใจในรายการ[e for number in xrange(n)]สำหรับแต่ละรายการได้อย่างไร

คำตอบ:


778

คุณยังสามารถเขียน:

[e] * n

คุณควรทราบว่าถ้า e เป็นรายการว่างเปล่าคุณจะได้รับรายการที่มีการอ้างอิง n ไปยังรายการเดียวกันไม่ใช่ n รายการว่างเปล่าอิสระ

การทดสอบประสิทธิภาพ

เมื่อดูอย่างรวดเร็วดูเหมือนว่าการทำซ้ำเป็นวิธีที่เร็วที่สุดในการสร้างรายการที่มีองค์ประกอบเหมือนกัน:

>>> timeit.timeit('itertools.repeat(0, 10)', 'import itertools', number = 1000000)
0.37095273281943264
>>> timeit.timeit('[0] * 10', 'import itertools', number = 1000000)
0.5577236771712819

แต่เดี๋ยวก่อน - มันไม่ใช่การทดสอบที่ยุติธรรม ...

>>> itertools.repeat(0, 10)
repeat(0, 10)  # Not a list!!!

ฟังก์ชั่นitertools.repeatไม่ได้สร้างรายการจริง ๆ เพียงแค่สร้างวัตถุที่สามารถใช้สร้างรายการได้หากคุณต้องการ! ลองอีกครั้ง แต่เปลี่ยนเป็นรายการ:

>>> timeit.timeit('list(itertools.repeat(0, 10))', 'import itertools', number = 1000000)
1.7508119747063233

[e] * nดังนั้นหากคุณต้องการรายการการใช้งาน repeatหากคุณต้องการที่จะสร้างองค์ประกอบซมใช้


23
ไม่น่าเป็นไปได้อย่างมากว่าประสิทธิภาพในการสร้างรายการที่มีองค์ประกอบเหมือนกันจะเป็นองค์ประกอบที่สำคัญของประสิทธิภาพของโปรแกรมไพ ธ อน
Arthur

11
ดังที่กล่าวไว้ข้างต้นหาก e เป็นรายการว่างเปล่า[[]] * nสามารถสร้างผลลัพธ์ที่ไม่คาดคิด ในการสร้างรายการย่อยที่ไม่ซ้ำให้ใช้เพื่อความเข้าใจ:[[] for i in range(0,n)]
Josiah Yoder

149
>>> [5] * 4
[5, 5, 5, 5]

ระวังเมื่อรายการที่ถูกทำซ้ำเป็นรายการ รายการจะไม่ถูกโคลน: องค์ประกอบทั้งหมดจะอ้างถึงรายการเดียวกัน!

>>> x=[5]
>>> y=[x] * 4
>>> y
[[5], [5], [5], [5]]
>>> y[0][0] = 6
>>> y
[[6], [6], [6], [6]]

80

สร้างรายการของรายการเดียวซ้ำ n ครั้งใน Python

รายการที่ไม่เปลี่ยนรูป

สำหรับรายการที่ไม่เปลี่ยนรูปเช่น None, bools, ints, floats, strings, tuples หรือ frozensets คุณสามารถทำได้ดังนี้:

[e] * 4

โปรดทราบว่าสิ่งนี้ดีที่สุดที่ใช้กับรายการที่ไม่เปลี่ยนรูป (สตริง, tuples, frozensets) ในรายการเท่านั้นเนื่องจากรายการเหล่านั้นชี้ไปที่รายการเดียวกันในสถานที่เดียวกันในหน่วยความจำ ฉันใช้สิ่งนี้บ่อยครั้งเมื่อฉันต้องสร้างตารางที่มีสคีมาของสตริงทั้งหมดดังนั้นฉันจึงไม่ต้องให้การแมปซ้ำซ้อนสูงแบบหนึ่งต่อหนึ่ง

schema = ['string'] * len(columns)

รายการที่ไม่แน่นอน

ฉันใช้ Python มานานแล้วและฉันไม่เคยเห็นกรณีการใช้งานที่ฉันจะทำข้างต้นด้วยอินสแตนซ์ที่ไม่แน่นอน ในการรับพูดรายการว่างเปล่าที่ไม่แน่นอนตั้งค่าหรือ dict คุณควรทำสิ่งนี้:

list_of_lists = [[] for _ in columns]

เครื่องหมายขีดล่างเป็นเพียงชื่อตัวแปรที่ใช้ในบริบทนี้

หากคุณมีเพียงตัวเลขนั่นก็คือ:

list_of_lists = [[] for _ in range(4)]

_ไม่ได้เป็นพิเศษจริงๆ แต่ตรวจสอบรูปแบบสภาพแวดล้อมการเข้ารหัสของคุณอาจจะบ่นถ้าคุณไม่ได้ตั้งใจที่จะใช้ตัวแปรและใช้ชื่ออื่น ๆ


คำเตือนสำหรับการใช้วิธีที่เปลี่ยนรูปไม่ได้กับรายการที่ไม่แน่นอน:

ระวังการทำเช่นนี้ด้วยวัตถุที่ไม่แน่นอนเมื่อคุณเปลี่ยนหนึ่งในพวกเขาพวกเขาทั้งหมดเปลี่ยนเพราะพวกเขาทั้งหมดวัตถุเดียวกัน :

foo = [[]] * 4
foo[0].append('x')

foo ส่งคืน:

[['x'], ['x'], ['x'], ['x']]

แต่ด้วยวัตถุที่ไม่เปลี่ยนรูปแบบคุณสามารถทำให้มันทำงานได้เพราะคุณเปลี่ยนการอ้างอิงไม่ใช่วัตถุ:

>>> l = [0] * 4
>>> l[0] += 1
>>> l
[1, 0, 0, 0]

>>> l = [frozenset()] * 4
>>> l[0] |= set('abc')
>>> l
[frozenset(['a', 'c', 'b']), frozenset([]), frozenset([]), frozenset([])]

แต่อีกครั้งวัตถุที่ไม่แน่นอนจะไม่ดีสำหรับเรื่องนี้เพราะการดำเนินการในสถานที่เปลี่ยนวัตถุไม่ใช่การอ้างอิง:

l = [set()] * 4
>>> l[0] |= set('abc')    
>>> l
[set(['a', 'c', 'b']), set(['a', 'c', 'b']), set(['a', 'c', 'b']), set(['a', 'c', 'b'])]

26

Itertools มีฟังก์ชั่นสำหรับการ:

import itertools
it = itertools.repeat(e,n)

แน่นอนitertoolsให้ตัววนซ้ำแทนรายการ [e] * nให้รายการ แต่ขึ้นอยู่กับสิ่งที่คุณจะทำกับลำดับเหล่านั้นitertoolsตัวแปรอาจมีประสิทธิภาพมากขึ้น


13

ดังที่คนอื่น ๆ ชี้ให้เห็นการใช้ตัวดำเนินการ * สำหรับวัตถุที่ไม่แน่นอนที่ซ้ำกันได้อ้างอิงซ้ำดังนั้นหากคุณเปลี่ยนสิ่งที่คุณเปลี่ยนแปลงพวกเขาทั้งหมด หากคุณต้องการสร้างอินสแตนซ์อิสระของวัตถุที่ไม่แน่นอนไวยากรณ์ xrange ของคุณเป็นวิธี Pythonic ที่สุดในการทำเช่นนี้ หากคุณกังวลกับการตั้งชื่อตัวแปรที่ไม่เคยใช้คุณสามารถใช้ตัวแปร underscore ที่ไม่ระบุชื่อได้

[e for _ in xrange(n)]

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.