python अलग-अलग प्रारंभिक सेट से टुपल्स क्यों बनाए जाते हैं?




set comparison (4)

यहां खेलने के लिए दो चीजें हैं।

  1. सेट अनियंत्रित हैं। set([1, "a", "b", "c", "z", "f"])) == set(["a", "b", "c", "z", "f", 1])

  2. जब आप एक सेट को tuple कंस्ट्रक्टर के माध्यम से tuple परिवर्तित करते हैं तो यह सेट पर अनिवार्य रूप से पुनरावृत्त होता है और पुनरावृति द्वारा लौटाए गए प्रत्येक तत्व को जोड़ता है।

टुपल्स के लिए कंस्ट्रक्टर सिंटैक्स है

tuple(iterable) -> tuple initialized from iterable's items

tuple(set([1, "a", "b", "c", "z", "f"])) कॉल करना tuple(set([1, "a", "b", "c", "z", "f"])) कॉलिंग tuple([i for i in set([1, "a", "b", "c", "z", "f"])])

के लिए मूल्य

[i for i in set([1, "a", "b", "c", "z", "f"])]

तथा

[i for i in set(["a", "b", "c", "z", "f", 1])]

वही हैं जो एक ही सेट पर पुनरावृत्त होते हैं।

EDIT धन्यवाद @ZeroPiraeus (उनके answer जाँच करें)। इसकी गारंटी नहीं है। पुनरावृत्ति का मान हमेशा समान सेट के लिए भी समान नहीं होगा।

टपल निर्माता को उस क्रम का पता नहीं है जिसमें सेट का निर्माण किया गया है।

मुझे निम्नलिखित दो टुपल्स की उम्मीद थी

>>> x = tuple(set([1, "a", "b", "c", "z", "f"]))
>>> y = tuple(set(["a", "b", "c", "z", "f", 1]))

असमान की तुलना करने के लिए, लेकिन वे नहीं हैं:

>>> x == y
>>> True

ऐसा क्यों है?


पहली नज़र में, ऐसा प्रतीत होता है कि x को हमेशा बराबर होना चाहिए, क्योंकि समान तत्वों से निर्मित दो सेट हमेशा बराबर होते हैं:

>>> x = set([1, "a", "b", "c", "z", "f"])
>>> y = set(["a", "b", "c", "z", "f", 1])
>>> x
{1, 'z', 'a', 'b', 'c', 'f'}
>>> y
{1, 'z', 'a', 'b', 'c', 'f'}
>>> x == y
True

हालांकि , यह हमेशा ऐसा नहीं होता है कि दो समान सेटों से निर्मित ट्यूपल्स (या अन्य ऑर्डर किए गए संग्रह) समान हैं।

वास्तव में, आपकी तुलना का परिणाम कभी-कभी True और कभी-कभी False , कम से कम पायथन> = 3.3 में। निम्नलिखित कोड का परीक्षण:

# compare.py
x = tuple(set([1, "a", "b", "c", "z", "f"]))
y = tuple(set(["a", "b", "c", "z", "f", 1]))
print(x == y)

... एक हजार गुणा:

$ for x in {1..1000}
> do
>   python3.3 compare.py
> done | sort | uniq -c
147 False
853 True

ऐसा इसलिए है, क्योंकि Python 3.3 के बाद से, strings, बाइट्स और डेटाटाइम्स के हैश मानों को सुरक्षा फिक्स के परिणामस्वरूप यादृच्छिक किया जाता है। हैश क्या है, इस पर निर्भर करते हुए, "टकराव" हो सकता है, जिसका अर्थ होगा कि ऑर्डर आइटम अंतर्निहित सरणी में संग्रहीत किए जाते हैं (और इसलिए पुनरावृति क्रम) सम्मिलन आदेश पर निर्भर करता है।

यहाँ डॉक्स से प्रासंगिक बिट है:

सुरक्षा में सुधार:

  • हैश रैंडमाइजेशन को डिफ़ॉल्ट रूप से स्विच किया जाता है।

- https://docs.python.org/3/whatsnew/3.3.html

संपादित करें : चूंकि यह टिप्पणियों में उल्लेख किया गया है कि ऊपर True / False अनुपात सतही रूप से आश्चर्यजनक है ...

शब्दकोशों की तरह सेट को हैश टेबल के रूप में लागू किया जाता है - इसलिए यदि कोई टक्कर है, तो तालिका में आइटम का क्रम (और इसलिए क्रम) दोनों पर निर्भर करेगा कि कौन सा आइटम पहले जोड़ा गया था (इस मामले में x और y में भिन्न) ) और हैशिंग के लिए इस्तेमाल किया जाने वाला बीज (3.3 के बाद से पायथन चालान में भिन्न)। चूंकि टकराव डिजाइन द्वारा दुर्लभ होते हैं, और इस प्रश्न में उदाहरण छोटे सेट हैं, इसलिए यह समस्या उतनी बार नहीं उठती है जितनी कि शुरू में कोई मान सकता है।

पायथन के शब्दकोशों और सेटों के कार्यान्वयन की गहन व्याख्या के लिए, द माइटी डिक्शनरी देखें


इसलिए आपके पास दो सूचियाँ हैं - जिनकी सामग्री समान है लेकिन विभिन्न क्रमों में, आप उन्हें सेट में परिवर्तित करते हैं - जो समान होंगी, क्योंकि उनके पास समान सामग्री होगी।

जब आप उन सेटों को ट्यूपल्स में बदलते हैं, तो वे उसी क्रम में परिवर्तित हो जाएंगे, क्योंकि वे एक ही सेट हैं, इसलिए ट्यूपल्स समान होंगे।

यह Python2.7 में सच है - लेकिन 3.3 के बाद से जब हैश को यादृच्छिक किया जाता है तो आप इसकी गारंटी नहीं दे पाएंगे - दो सेटों के रूप में, हालांकि समान क्रम में सामग्री में समान रूप से पुनरावृति नहीं होगी।


सेट का आदेश नहीं दिया जाता है और केवल उनकी सदस्यता द्वारा परिभाषित किया जाता है।

उदाहरण के लिए, set([1, 2]) == set([2, 1])

यदि प्रत्येक स्थान पर उनके सदस्य समान हैं, तो ट्यूपल्स समान हैं, लेकिन चूंकि संग्रह टुपल्स समान रूप से (बढ़ते क्रम में) से पुनरावृति से बनाए गए थे, टुपल्स समान होने के साथ समाप्त होते हैं।





hashtable