ฉันต้องการสร้างชุดรายการความยาวผันแปรทั้งหมด แต่ละรายการจะมีองค์ประกอบเดียวกันe
ซ้ำn
ครั้ง (โดยที่n
= ความยาวของรายการ)
ฉันจะสร้างรายการโดยไม่ต้องใช้ความเข้าใจในรายการ[e for number in xrange(n)]
สำหรับแต่ละรายการได้อย่างไร
ฉันต้องการสร้างชุดรายการความยาวผันแปรทั้งหมด แต่ละรายการจะมีองค์ประกอบเดียวกันe
ซ้ำn
ครั้ง (โดยที่n
= ความยาวของรายการ)
ฉันจะสร้างรายการโดยไม่ต้องใช้ความเข้าใจในรายการ[e for number in xrange(n)]
สำหรับแต่ละรายการได้อย่างไร
คำตอบ:
คุณยังสามารถเขียน:
[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
หากคุณต้องการที่จะสร้างองค์ประกอบซมใช้
[[]] * n
สามารถสร้างผลลัพธ์ที่ไม่คาดคิด ในการสร้างรายการย่อยที่ไม่ซ้ำให้ใช้เพื่อความเข้าใจ:[[] for i in range(0,n)]
>>> [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]]
สร้างรายการของรายการเดียวซ้ำ 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'])]
Itertools มีฟังก์ชั่นสำหรับการ:
import itertools
it = itertools.repeat(e,n)
แน่นอนitertools
ให้ตัววนซ้ำแทนรายการ [e] * n
ให้รายการ แต่ขึ้นอยู่กับสิ่งที่คุณจะทำกับลำดับเหล่านั้นitertools
ตัวแปรอาจมีประสิทธิภาพมากขึ้น
ดังที่คนอื่น ๆ ชี้ให้เห็นการใช้ตัวดำเนินการ * สำหรับวัตถุที่ไม่แน่นอนที่ซ้ำกันได้อ้างอิงซ้ำดังนั้นหากคุณเปลี่ยนสิ่งที่คุณเปลี่ยนแปลงพวกเขาทั้งหมด หากคุณต้องการสร้างอินสแตนซ์อิสระของวัตถุที่ไม่แน่นอนไวยากรณ์ xrange ของคุณเป็นวิธี Pythonic ที่สุดในการทำเช่นนี้ หากคุณกังวลกับการตั้งชื่อตัวแปรที่ไม่เคยใช้คุณสามารถใช้ตัวแปร underscore ที่ไม่ระบุชื่อได้
[e for _ in xrange(n)]
[e] * n
ควรทำงาน