Yanıtlar:
Bunun gibi:
>>> keys = ['a', 'b', 'c']
>>> values = [1, 2, 3]
>>> dictionary = dict(zip(keys, values))
>>> print(dictionary)
{'a': 1, 'b': 2, 'c': 3}
Voila :-) Çift dict
yapıcı ve zip
işlev çok faydalıdır: https://docs.python.org/3/library/functions.html#func-dict
{thing}
sentetik şekerdir set()
. birkaç element içeren {*iterable}
bir sentetik şekerdir set
. {k:v}
ya {**mapping}
da bir inşa edecekdict
, ama bu sözdizimsel olarak oldukça farklı.
{}
sözlükler için sintaks kullanıyorum . Aslında, denersek type({})
çıktı olur dict
. Ama gerçekten, eğer denersek, type({thing})
çıktı olur set
.
{k:v for k, v in zip(keys, values)}
. Olabiliriz. +1.
Sahip olduğunuzu hayal edin:
keys = ('name', 'age', 'food') values = ('Monty', 42, 'spam')
Aşağıdaki sözlüğü oluşturmanın en basit yolu nedir?
dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
dict
yapıcızip
new_dict = dict(zip(keys, values))
Python 3'te zip artık tembel bir yineleyici döndürüyor ve bu şimdi en performanslı yaklaşım.
dict(zip(keys, values))
için bir defalık küresel arama her gerektirir dict
ve zip
ancak herhangi bir ara gereksiz veri yapıları oluşturmak veya fonksiyon uygulamasında yerel aramalar ile uğraşmak zorunda değildir.
Dict yapıcısını kullanmaya yakından bakan, bir dict kavramasının yerel sözdizimini kullanmaktır ( diğerleri yanlışlıkla koyduğu gibi bir liste kavrama değil):
new_dict = {k: v for k, v in zip(keys, values)}
Anahtarlara veya değere göre eşlemeniz veya filtrelemeniz gerektiğinde bunu seçin.
Python 2'de, zip
gereksiz bir liste oluşturmaktan kaçınmak için bir liste döndürür, izip
bunun yerine kullanın (zip'e takma adı Python 3'e geçtiğinizde kod değişikliklerini azaltabilir).
from itertools import izip as zip
Bu hala (2.7):
new_dict = {k: v for k, v in zip(keys, values)}
izip
dan itertools
olur zip
Python 3'te izip
Python 2 için zip daha iyidir 2.6 veya altı için ve ideali (gereksiz liste oluşturulmasını önler çünkü):
from itertools import izip
new_dict = dict(izip(keys, values))
Her durumda:
>>> new_dict
{'age': 42, 'name': 'Monty', 'food': 'spam'}
Eğer yardım konusuna dict
bakarsak, bunun çeşitli biçimler aldığını görürüz:
>>> help(dict)
class dict(object)
| dict() -> new empty dictionary
| dict(mapping) -> new dictionary initialized from a mapping object's
| (key, value) pairs
| dict(iterable) -> new dictionary initialized as if via:
| d = {}
| for k, v in iterable:
| d[k] = v
| dict(**kwargs) -> new dictionary initialized with the name=value pairs
| in the keyword argument list. For example: dict(one=1, two=2)
En uygun yaklaşım, gereksiz veri yapıları oluşturmaktan kaçınarak yinelenebilir bir yöntem kullanmaktır. Python 2'de zip, gereksiz bir liste oluşturur:
>>> zip(keys, values)
[('name', 'Monty'), ('age', 42), ('food', 'spam')]
Python 3'te eşdeğer:
>>> list(zip(keys, values))
[('name', 'Monty'), ('age', 42), ('food', 'spam')]
ve Python 3 zip
sadece tekrarlanabilir bir nesne yaratır:
>>> zip(keys, values)
<zip object at 0x7f0e2ad029c8>
Gereksiz veri yapıları oluşturmaktan kaçınmak istediğimizden, genellikle Python 2'lerden kaçınmak isteriz zip
(gereksiz bir liste oluşturduğundan).
Bu, kurucu kurucuya iletilen bir üretici ifadesidir:
generator_expression = ((k, v) for k, v in zip(keys, values))
dict(generator_expression)
Veya eşdeğer olarak:
dict((k, v) for k, v in zip(keys, values))
Ve bu, kurucu kurucuya aktarılan bir liste kavramasıdır:
dict([(k, v) for k, v in zip(keys, values)])
İlk iki durumda, fermuarın üzerine ek bir operatif olmayan (dolayısıyla gereksiz) hesaplama katmanı yerleştirilir ve listenin anlaşılması durumunda, gereksiz bir ekstra liste oluşturulur. Hepsinin daha az performans göstermesini ve kesinlikle daha fazla olmasını beklemem.
Nix tarafından sağlanan 64 bit Python 3.8.2'de Ubuntu 16.04'te en hızlıdan en yavaşına doğru sıralandı:
>>> min(timeit.repeat(lambda: dict(zip(keys, values))))
0.6695233230129816
>>> min(timeit.repeat(lambda: {k: v for k, v in zip(keys, values)}))
0.6941362579818815
>>> min(timeit.repeat(lambda: {keys[i]: values[i] for i in range(len(keys))}))
0.8782548159942962
>>>
>>> min(timeit.repeat(lambda: dict([(k, v) for k, v in zip(keys, values)])))
1.077607496001292
>>> min(timeit.repeat(lambda: dict((k, v) for k, v in zip(keys, values))))
1.1840861019445583
dict(zip(keys, values))
küçük anahtar ve değer kümeleriyle bile kazanır, ancak daha büyük kümeler için performans farklılıkları artar.
Bir yorumcu şunları söyledi:
min
performansı karşılaştırmanın kötü bir yolu gibi görünüyor. Elbettemean
ve / veyamax
gerçek kullanım için çok daha yararlı göstergeler olacaktır.
Biz kullanmak min
bu algoritmalar deterministik çünkü. Algoritmaların performansını mümkün olan en iyi koşullar altında bilmek istiyoruz.
İşletim sistemi herhangi bir nedenle askıda kalırsa, karşılaştırmaya çalıştığımız şeyle ilgisi yoktur, bu nedenle bu tür sonuçları analizimizden hariç tutmamız gerekir.
Kullandığımız takdirde mean
, olayların bu tür büyük ölçüde sonuçlarını saptırma olur ve biz kullanılırsa max
biz sadece en uç sonuç alırsınız - büyük olasılıkla böyle bir olay etkilenen biri.
Bir yorumcu ayrıca şunları söylüyor:
Python 3.6.8'de, ortalama değerleri kullanarak, bu küçük listeler için dikte anlama gerçekten daha hızlıdır, yaklaşık% 30 oranındadır. Daha büyük listeler için (10k rasgele sayılar),
dict
arama yaklaşık% 10 daha hızlıdır.
Sanırım dict(zip(...
10k rasgele sayılarla kastediyoruz . Bu oldukça sıra dışı bir kullanım durumu gibi geliyor. Büyük veri kümelerinde en doğrudan çağrıların baskın olacağı mantıklıdır ve bu testi çalıştırmanın ne kadar süreceği ve sayılarınızı daha da arttırarak işletim sistemi askıda kalıyorsa şaşırmam. Ve eğer kullanırsanız mean
ya da max
sonuçlarınızı anlamsız olarak değerlendirirsem.
En iyi örneklerimizde daha gerçekçi bir boyut kullanalım:
import numpy
import timeit
l1 = list(numpy.random.random(100))
l2 = list(numpy.random.random(100))
Ve burada görüyoruz ki dict(zip(...
, bu daha büyük veri kümeleri için yaklaşık% 20 daha hızlı çalışıyor.
>>> min(timeit.repeat(lambda: {k: v for k, v in zip(l1, l2)}))
9.698965263989521
>>> min(timeit.repeat(lambda: dict(zip(l1, l2))))
7.9965161079890095
dict(zip(headList, textList))
& 1.95 \ pm 0.030 microsec değerini döndürür {k: v for k, v in zip(headList, textList)}
. Öncekini okunabilirlik ve hız için öneririm. Açıkçası bu timeit için min () vs mean () argümanına ulaşır.
min
performansı karşılaştırmanın kötü bir yolu gibi görünüyor. Elbette mean
ve / veya max
gerçek kullanım için çok daha yararlı göstergeler olacaktır.
dict
arama yaklaşık% 10 daha hızlıdır.
Bunu dene:
>>> import itertools
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> adict = dict(itertools.izip(keys,values))
>>> adict
{'food': 'spam', 'age': 42, 'name': 'Monty'}
Python 2'de, bellek tüketiminde kıyasla daha ekonomiktir zip
.
zip
bellek tüketiminde zaten ekonomiktir. docs.python.org/3/library/functions.html#zip Aslında, Python 3'ün Python 2 pythonhosted.org/six yerine değiştirmek için six
kullandığını görebilirsiniz . zip
itertools.izip
Python ≥ 2.7'de sözlük anlamlarını da kullanabilirsiniz:
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> {k: v for k, v in zip(keys, values)}
{'food': 'spam', 'age': 42, 'name': 'Monty'}
Daha doğal bir yol sözlük anlamayı kullanmaktır
keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')
dict = {keys[i]: values[i] for i in range(len(keys))}
dict
nesneye dönüştürmek en yavaş , neden öyle ?, teşekkürler dostum.
Sözlük oluşturmadan önce anahtarları veya değerleri dönüştürmeniz gerekiyorsa, bir jeneratör ifadesi kullanılabilir. Misal:
>>> adict = dict((str(k), v) for k, v in zip(['a', 1, 'b'], [2, 'c', 3]))
Bir göz atın Pythonista gibi kod: Deyimsel Python .
Python 3.x ile diksiyon kavramaya gider
keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')
dic = {k:v for k,v in zip(keys, values)}
print(dic)
Diksiyon kavrayışları hakkında daha fazla bilgi için bir örnek var:
>>> print {i : chr(65+i) for i in range(4)}
{0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'}
Basit koda ihtiyaç duyan ve aşina olmayanlar için zip
:
List1 = ['This', 'is', 'a', 'list']
List2 = ['Put', 'this', 'into', 'dictionary']
Bu bir kod satırı ile yapılabilir:
d = {List1[n]: List2[n] for n in range(len(List1))}
List1
daha uzunsa yüksek sesle başarısızList2
for n in range(len(List1))
bir anti-desen
En iyi çözüm hala:
In [92]: keys = ('name', 'age', 'food')
...: values = ('Monty', 42, 'spam')
...:
In [93]: dt = dict(zip(keys, values))
In [94]: dt
Out[94]: {'age': 42, 'food': 'spam', 'name': 'Monty'}
Alıştırma yapın:
lst = [('name', 'Monty'), ('age', 42), ('food', 'spam')]
keys, values = zip(*lst)
In [101]: keys
Out[101]: ('name', 'age', 'food')
In [102]: values
Out[102]: ('Monty', 42, 'spam')
Aşağıdaki kodu kullanabilirsiniz:
dict(zip(['name', 'age', 'food'], ['Monty', 42, 'spam']))
Ancak listelerin uzunluğunun aynı olduğundan emin olun. Uzunluk aynı değilse, zip işlevi daha uzun olanı çevirir.
Grafikle ilgili bir sorunu çözmeye çalışırken bu şüphem vardı. Sahip olduğum sorun, boş bir bitişik liste tanımlamam gerekiyordu ve tüm düğümleri boş bir listeyle başlatmak istedim, o zaman yeterince hızlı olup olmadığını nasıl kontrol edeceğimi düşündüm, yani bir zip işlemi yapmaya değip değmeyeceğini düşündüm basit atama anahtar / değer çifti yerine. Çoğu zaman, zaman faktörü önemli bir buz kırıcıdır. Bu yüzden her iki yaklaşım için de timeit operasyonu yaptım.
import timeit
def dictionary_creation(n_nodes):
dummy_dict = dict()
for node in range(n_nodes):
dummy_dict[node] = []
return dummy_dict
def dictionary_creation_1(n_nodes):
keys = list(range(n_nodes))
values = [[] for i in range(n_nodes)]
graph = dict(zip(keys, values))
return graph
def wrapper(func, *args, **kwargs):
def wrapped():
return func(*args, **kwargs)
return wrapped
iteration = wrapper(dictionary_creation, n_nodes)
shorthand = wrapper(dictionary_creation_1, n_nodes)
for trail in range(1, 8):
print(f'Itertion: {timeit.timeit(iteration, number=trails)}\nShorthand: {timeit.timeit(shorthand, number=trails)}')
N_nodes = 10,000,000 için anladım,
Yineleme: 2.825081646999024 Kestirme: 3.535717916001886
Yineleme: 5.051560923002398 Kestirme: 6.255070794999483
Yineleme: 6.52859034499852 Kestirme: 8.221581164998497
Yineleme: 8.683652416999394 Kestirme: 12.599181543999293
Yineleme: 11.587241565001023 Kestirme: 15.27298851100204
Yineleme: 14.816342867001367 Kestirme: 17.162912737003353
Yineleme: 16.645022411001264 Kestirme: 19.976680120998935
Belirli bir noktadan sonra n_th adımda yineleme yaklaşımının n-1_th adımda steno yaklaşım ile harcanan süreyi aştığını açıkça görebilirsiniz.
Ayrıca, sözlüğünüze liste değeri ekleme örneği
list1 = ["Name", "Surname", "Age"]
list2 = [["Cyd", "JEDD", "JESS"], ["DEY", "AUDIJE", "PONGARON"], [21, 32, 47]]
dic = dict(zip(list1, list2))
print(dic)
daima "Anahtarınızın" (liste1) daima ilk parametrede olduğundan emin olun.
{'Name': ['Cyd', 'JEDD', 'JESS'], 'Surname': ['DEY', 'AUDIJE', 'PONGARON'], 'Age': [21, 32, 47]}
Ayrıca, iki listenin birleşimi olan bir liste ile de deneyebilirsiniz;)
a = [1,2,3,4]
n = [5,6,7,8]
x = []
for i in a,n:
x.append(i)
print(dict(zip(x[0], x[1])))
zip fonksiyonu olmayan yöntem
l1 = [1,2,3,4,5]
l2 = ['a','b','c','d','e']
d1 = {}
for l1_ in l1:
for l2_ in l2:
d1[l1_] = l2_
l2.remove(l2_)
break
print (d1)
{1: 'd', 2: 'b', 3: 'e', 4: 'a', 5: 'c'}
dictionary = {zip(keys, values)}
yaramayacağını belirtmek gerekir . Açıkça ilan etmelisinizdict(...)