Farklı uzunluklarda listeler oluşturmak istiyorum. Her liste e
tekrar 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 ?
Farklı uzunluklarda listeler oluşturmak istiyorum. Her liste e
tekrar 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:
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.repeat
aslı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
.
[[]] * n
beklenmedik sonuçlar doğurabilir. Benzersiz boş alt listeler oluşturmak için kavrama için kullanın:[[] for i in range(0,n)]
Python'da Tekrarlanan Tek Öğe Listesi Oluşturma
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)
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.
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'])]
Itertools'un sadece bunun için bir işlevi vardır:
import itertools
it = itertools.repeat(e,n)
Tabii ki itertools
size bir liste yerine bir yineleyici verir. [e] * n
size bir liste verir, ancak bu dizilerle ne yapacağınıza bağlı olarak, itertools
varyant çok daha verimli olabilir.
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)]
[e] * n
çalışmalı