سؤال

تخيل أن لديك:

keys = ['name', 'age', 'food']
values = ['Monty', 42, 'spam']

ما هي أبسط طريقة لإنتاج القاموس التالي؟

a_dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
هل كانت مفيدة؟

المحلول

ومثل هذا:

>>> keys = ['a', 'b', 'c']
>>> values = [1, 2, 3]
>>> dictionary = dict(zip(keys, values))
>>> print(dictionary)
{'a': 1, 'b': 2, 'c': 3}

وفويلا صحيت منشئ dict البشرى وظيفة zip مفيدة بذهول: <لأ href = "https://docs.python.org/3/library/functions.html#func-dict" يختلط = "noreferrer" > https://docs.python.org/3/library/functions.html#func-dict

نصائح أخرى

وجرب هذا:

>>> import itertools
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> adict = dict(itertools.izip(keys,values))
>>> adict
{'food': 'spam', 'age': 42, 'name': 'Monty'}

في بايثون 2، كما انها أكثر اقتصادا في استهلاك الذاكرة مقارنة zip.

تخيل أن لديك:

keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')

ما هي أبسط طريقة لإنتاج القاموس التالي؟

dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}

الأكثر أداءً - Python 2.7 و3، فهم الإملاء:

أحد التحسينات المحتملة على استخدام مُنشئ الإملاء هو استخدام البنية الأصلية لفهم الإملاء (وليس فهم القائمة، كما وضعها الآخرون بشكل خاطئ):

new_dict = {k: v for k, v in zip(keys, values)}

في بايثون 2، zip إرجاع قائمة، لتجنب إنشاء قائمة غير ضرورية، استخدم izip بدلاً من ذلك (الاسم المستعار لـ Zip يمكن أن يقلل من تغييرات التعليمات البرمجية عند الانتقال إلى Python 3).

from itertools import izip as zip

لذلك لا يزال هذا:

new_dict = {k: v for k, v in zip(keys, values)}

Python 2، مثالي لـ <= 2.6

izip من itertools يصبح zip في بايثون 3. izip أفضل من Zip لـ Python 2 (لأنه يتجنب إنشاء القائمة غير الضرورية)، ومثالي لـ 2.6 أو أقل:

from itertools import izip
new_dict = dict(izip(keys, values))

بايثون 3

في بايثون 3، zip تصبح نفس الوظيفة التي كانت في itertools الوحدة النمطية، بحيث تكون ببساطة:

new_dict = dict(zip(keys, values))

سيكون فهم الإملاء أكثر أداءً (راجع مراجعة الأداء في نهاية هذه الإجابة).

النتائج لجميع الحالات:

في جميع الحالات:

>>> new_dict
{'age': 42, 'name': 'Monty', 'food': 'spam'}

توضيح:

إذا نظرنا إلى المساعدة على dict نرى أن الأمر يأخذ أشكالًا متنوعة من الحجج:

>>> 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)

النهج الأمثل هو استخدام التكرار مع تجنب إنشاء هياكل البيانات غير الضرورية.في Python 2، يقوم Zip بإنشاء قائمة غير ضرورية:

>>> zip(keys, values)
[('name', 'Monty'), ('age', 42), ('food', 'spam')]

في بايثون 3، سيكون المعادل:

>>> list(zip(keys, values))
[('name', 'Monty'), ('age', 42), ('food', 'spam')]

و بايثون 3 zip مجرد إنشاء كائن قابل للتكرار:

>>> zip(keys, values)
<zip object at 0x7f0e2ad029c8>

نظرًا لأننا نريد تجنب إنشاء هياكل بيانات غير ضرورية، فإننا عادةً نرغب في تجنب Python 2 zip (لأنه ينشئ قائمة غير ضرورية).

البدائل الأقل أداءً:

هذا هو تعبير المولد الذي يتم تمريره إلى مُنشئ الإملاء:

generator_expression = ((k, v) for k, v in zip(keys, values))
dict(generator_expression)

أو مكافئ:

dict((k, v) for k, v in zip(keys, values))

وهذه قائمة فهم يتم تمريرها إلى مُنشئ الإملاء:

dict([(k, v) for k, v in zip(keys, values)])

في الحالتين الأوليين، يتم وضع طبقة إضافية من الحسابات غير العملية (وبالتالي غير الضرورية) فوق الملف المضغوط القابل للتكرار، وفي حالة فهم القائمة، يتم إنشاء قائمة إضافية دون داعٍ.أتوقع منهم جميعًا أن يكونوا أقل أداءً، وبالتأكيد ليس أكثر من ذلك.

مراجعة الأداء:

في إصدار 64 بت من Python 3.4.3، على Ubuntu 14.04، تم الترتيب من الأسرع إلى الأبطأ:

>>> min(timeit.repeat(lambda: {k: v for k, v in zip(keys, values)}))
0.7836067057214677
>>> min(timeit.repeat(lambda: dict(zip(keys, values))))
1.0321204089559615
>>> min(timeit.repeat(lambda: {keys[i]: values[i] for i in range(len(keys))}))
1.0714934510178864
>>> min(timeit.repeat(lambda: dict([(k, v) for k, v in zip(keys, values)])))
1.6110592018812895
>>> min(timeit.repeat(lambda: dict((k, v) for k, v in zip(keys, values))))
1.7361853648908436
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> dict(zip(keys, values))
{'food': 'spam', 'age': 42, 'name': 'Monty'}

ويمكنك أيضا استخدام comprehensions القاموس في بيثون ≥ 2.7:

>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> {k: v for k, v in zip(keys, values)}
{'food': 'spam', 'age': 42, 'name': 'Monty'}

وهناك طريقة أكثر طبيعية لاستخدام الفهم القاموس

keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')    
dict = {keys[i]: values[i] for i in range(len(keys))}

إذا كنت بحاجة إلى تغيير مفاتيح أو القيم قبل إنشاء القاموس ثم مولد يمكن ان تستعمل. مثال:

>>> adict = dict((str(k), v) for k, v in zip(['a', 1, 'b'], [2, 'c', 3])) 

ونلقي نظرة كود مثل Pythonista: اصطلاحي بيثون .

وبالنسبة لأولئك الذين يحتاجون إلى رمز بسيط وليسوا على دراية zip:

List1 = ['This', 'is', 'a', 'list']
List2 = ['Put', 'this', 'into', 'dictionary']

ويمكن القيام بذلك عن طريق سطر واحد من التعليمات البرمجية:

d = {List1[n]: List2[n] for n in range(len(List1))}
  • 2018-04-18

الحل الأفضل لا يزال:

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'}

تبديل ذلك:

    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')

ويمكنك استخدام هذا رمز أدناه:

dict(zip(['name', 'age', 'food'], ['Monty', 42, 'spam']))

ولكن تأكد من أن طول القوائم سيتم same.If لمدة لا same.then وظيفة الرمز البريدي turncate يعد واحد.

وهنا أيضا مثال على إضافة قيمة قائمة فيكم القاموس

list1 = ["Name", "Surname", "Age"]
list2 = [["Cyd", "JEDD", "JESS"], ["DEY", "AUDIJE", "PONGARON"], [21, 32, 47]]
dic = dict(zip(list1, list2))
print(dic)

ودائما تأكد من أن لديك "مفتاح" (list1) هو دائما في المعلمة الأولى.

{'Name': ['Cyd', 'JEDD', 'JESS'], 'Surname': ['DEY', 'AUDIJE', 'PONGARON'], 'Age': [21, 32, 47]}

وطريقة بدون وظيفة الرمز

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'}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top