N kez tekrarlanan tek bir öğe listesi oluşturun


523

Farklı uzunluklarda listeler oluşturmak istiyorum. Her liste etekrar tekrar aynı öğeyi içerecektir n(burada n= listenin uzunluğu).

[e for number in xrange(n)]Her bir liste için liste kavrayışı kullanmadan listeleri nasıl oluşturabilirim ?

Yanıtlar:


778

Ayrıca şunu da yazabilirsiniz:

[e] * n

Eğer e boş bir liste ise, n boş bağımsız liste değil, aynı listeye n referansı olan bir liste aldığınız unutulmamalıdır.

Performans testi

İlk bakışta , n özdeş unsurlarla bir liste oluşturmanın en hızlı yolu tekrar gibi görünüyor :

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

Ama bekleyin - bu adil bir test değil ...

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

Fonksiyon itertools.repeataslında listeyi oluşturmaz, sadece bir liste oluşturmak için kullanılabilecek bir nesne oluşturur! Bunu tekrar deneyelim, ancak bir listeye dönüştürelim:

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

Yani bir liste istiyorsanız, kullanın [e] * n. Öğeleri tembel bir şekilde oluşturmak istiyorsanız, kullanın repeat.


23
Özdeş öğelerle bir liste oluşturma performansının bir python programının performansının kritik bir bileşeni olması pek olası değildir.
Arthur

11
Yukarıda belirtildiği gibi, e boş bir liste ise [[]] * nbeklenmedik sonuçlar doğurabilir. Benzersiz boş alt listeler oluşturmak için kavrama için kullanın:[[] for i in range(0,n)]
Josiah Yoder

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

Tekrarlanan öğe bir liste olduğunda dikkatli olun. Liste klonlanmayacak: tüm elemanlar aynı listeye atıfta bulunacak!

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

80

Python'da Tekrarlanan Tek Öğe Listesi Oluşturma

Değişmez ürünler

None, bools, ints, floats, string, tuples veya frozensets gibi değişmez öğeler için bunu şu şekilde yapabilirsiniz:

[e] * 4

Bunun yalnızca listedeki değişmez öğelerle (dizeler, tuples, frozensets,) kullanıldığını unutmayın, çünkü bunların hepsi aynı öğeyi bellekte aynı yere işaret eder. Tüm dizelerin şemasına sahip bir tablo oluşturmak zorunda kaldığımda bunu sık sık kullanıyorum, böylece çok fazla bire bir eşleme vermek zorunda değilim.

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

Değişken öğeler

Python'u uzun süredir kullanıyorum ve yukarıda değiştirilebilir bir örnekle yapacağım bir kullanım durumu görmedim. Bunun yerine, değişebilir boş bir liste almak, ayarlamak veya dikte etmek için şöyle bir şey yapmalısınız:

list_of_lists = [[] for _ in columns]

Alt çizgi, bu bağlamda basitçe değişken bir addır.

Yalnızca numaranız varsa, bu şöyle olur:

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

_Gerçekten özel değil, ama sen değişken kullanın ve diğer adı kullanmak niyetinde değilse sizin kodlama ortamı tarzı denetleyicisi muhtemelen şikayet edecektir.


Değişken yöntemlerle değişmez yöntemi kullanmak için uyarılar:

Bunu değişebilir nesnelerle yapmamaya dikkat edin , bunlardan birini değiştirdiğinizde hepsi değişir çünkü hepsi aynı nesnedir:

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

foo şimdi geri dönüyor:

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

Ancak değişmez nesnelerle, çalışmasını sağlayabilirsiniz, çünkü nesneyi değil referansı değiştirirsiniz:

>>> 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([])]

Ama yine de, değiştirilebilir nesneler bunun için iyi değildir, çünkü yerinde işlemler referansı değil nesneyi değiştirir:

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'un sadece bunun için bir işlevi vardır:

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

Tabii ki itertoolssize bir liste yerine bir yineleyici verir. [e] * nsize bir liste verir, ancak bu dizilerle ne yapacağınıza bağlı olarak, itertoolsvaryant çok daha verimli olabilir.


13

Diğerlerinin de işaret ettiği gibi, değişken bir nesne için * operatörünün kullanılması referansları çoğaltır, böylece birini değiştirirseniz hepsini değiştirirsiniz. Değişken bir nesnenin bağımsız örneklerini oluşturmak istiyorsanız, xrange sözdiziminiz bunu yapmanın en Pythonic yoludur. Asla kullanılmayan adlandırılmış bir değişkene sahipseniz, anonim alt çizgi değişkenini kullanabilirsiniz.

[e for _ in xrange(n)]

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.