क्या पायथन में दो चर को स्वैप करने के लिए एक मानकीकृत विधि है?


345

पायथन में, मैंने इस सिंटैक्स का उपयोग करते हुए दो चर मानों की अदला-बदली देखी है:

left, right = right, left

क्या इसे दो वैरिएबल मानों को स्वैप करने का मानक तरीका माना जाता है या कुछ अन्य साधन हैं जिनके द्वारा कन्वेंशन द्वारा दो वैरिएबल सबसे अधिक स्वैप किए जाते हैं?


1
@eyquem: यह केवल इस बात के लिए आता है कि क्या आदेश का मूल्यांकन भाषा द्वारा टपल / सूची असाइनमेंट के लिए परिभाषित किया गया है। पायथन करता है, ज्यादातर पुरानी भाषाएं नहीं हैं।
0

Hrmm C ++ में स्वैप (एक [i], [k]) क्यों है, हम अजगर के लिए ऐसा कुछ नहीं कर सकते।
निल्स

जवाबों:


389

पायथन बाएं से दाएं की ओर भावों का मूल्यांकन करता है। ध्यान दें कि असाइनमेंट का मूल्यांकन करते समय, दाएं हाथ का मूल्यांकन बाएं हाथ की तरफ से पहले किया जाता है।

http://docs.python.org/3/reference/expressions.html#evaluation-order

इसका मतलब है कि अभिव्यक्ति के लिए निम्नलिखित हैं a,b = b,a:

  • दाहिने हाथ की ओर b,aका मूल्यांकन किया जाता है, यह कहना है कि मेमोरी में दो तत्वों का एक समूह बनाया गया है। दो तत्व पहचानकर्ता द्वारा निर्दिष्ट वस्तुएं हैं bऔर a, जो कि कार्यक्रम के निष्पादन के दौरान निर्देश को एनक्रिप्ट करने से पहले मौजूद थे
  • इस ट्यूल के निर्माण के ठीक बाद, इस टपल ऑब्जेक्ट का कोई भी असाइनमेंट अभी भी नहीं बनाया गया है, लेकिन इससे कोई फर्क नहीं पड़ता, पायथन आंतरिक रूप से जानता है कि यह कहां है
  • फिर, बाएं हाथ की ओर का मूल्यांकन किया जाता है, यह कहना है कि ट्यूपल को बाएं हाथ की ओर सौंपा गया है
  • के रूप में बाएं ओर दो पहचानकर्ता से बना है, टपल आदेश है कि पहले पहचानकर्ता में पैक है aटपल के पहले तत्व को सौंपा जा (जो उद्देश्य यह है कि formely किया गया है स्वैप से पहले, क्योंकि यह नाम था b)
    और दूसरा पहचानकर्ता bटपल के दूसरे तत्व को सौंपा गया है (जो कि पूर्व में स्वैप से पहले एक वस्तु है क्योंकि इसका पहचानकर्ता था a)

इस तंत्र को प्रभावी ढंग से करने के लिए सौंपा पहचानकर्ता वस्तुओं बदली है aऔरb

तो, आपके प्रश्न का उत्तर देने के लिए: हाँ, यह दो वस्तुओं पर दो पहचानकर्ताओं को स्वैप करने का मानक तरीका है।
वैसे, वस्तुएं चर नहीं हैं, वे वस्तुएं हैं।


1
जहां तक ​​मैं समझता हूं, इस तरह से दो चर को स्वैप करने से अतिरिक्त मेमोरी का उपयोग नहीं होता है, केवल 2 चर के लिए स्मृति स्वयं, क्या मैं सही हूं?
19

1
@ टटपुलेट्स का निर्माण टपल का निर्माण कुछ अतिरिक्त मेमोरी लेगा (संभवतः स्वैप के 3-वैरिएबल संस्करण से अधिक होगा), लेकिन चूंकि केवल चीजों को स्वैप किया जा रहा है, स्मृति पते हैं, इसलिए यह निरपेक्ष में बहुत अधिक मेमोरी नहीं होगी भावना (शायद 24 अतिरिक्त बाइट्स)।
Brilliand

@ ब्रिलियनड: Thks। क्या आपके पास इस विषय के लिए कोई दस्तावेज हैं। यह काफी दिलचस्प है और मैं एक फ्यूचर पढ़ना चाहूंगा। धन्यवाद।
Catbuilts

1
@ कैटिगरी मैं निश्चित नहीं हूं, लेकिन यह पढ़ने में मदद कर सकता है कि C ++ पॉइंटर्स कैसे काम करते हैं। जबकि पायथन चीजों को स्वचालित रूप से आपके लिए सबसे अच्छा तरीका करने की कोशिश करता है, सी ++ वास्तव में आपको सभी संभव सही और गलत तरीकों से चीजें करने के लिए सभी विकल्प देता है, इसलिए यह सीखने का एक अच्छा प्रारंभिक बिंदु है कि पायथन के दृष्टिकोण में क्या कमियां हैं। । यह भी याद रखें कि "64-बिट" ऑपरेटिंग सिस्टम होने का मतलब है कि मेमोरी एड्रेस को स्टोर करने में 64 बिट मेमोरी लगती है - यही वह हिस्सा है जहां से मुझे मेरा "24 बाइट्स" नंबर मिला है।
ब्रिलियनैड

महान व्याख्या। बस यह जोड़ना कि यही कारण है कि आप इस विधि का उपयोग किसी भी संख्या में "चर" को पुनर्व्यवस्थित करने के लिए कर सकते हैं, उदाहरण के लिए a, b, c = c, a, b
एलिम्बाला87


38

मैं चर को स्वैप करने के तीन तरीके जानता हूं, लेकिन a, b = b, aसबसे सरल है। वहाँ है

XOR (पूर्णांकों के लिए)

x = x ^ y
y = y ^ x
x = x ^ y

या संक्षेप में,

x ^= y
y ^= x
x ^= y

अस्थायी चर

w = x
x = y
y = w
del w

टप्पल स्वैप

x, y = y, x

1
सबसे सरल है और केवल एक ही है जो बाधित नहीं है।
जॉर्ज लीताओ

17
XOR "चर" स्वैप नहीं करता है। यह पूर्णांक चर को स्वैप करता है। (या XOR ऑपरेटर को ठीक से लागू करने वाले कुछ अन्य प्रकार) इसके अलावा, चूंकि रोजाल्स्की के उत्तर के अनुसार, टपल स्वैप को दुभाषिया में अनुकूलित किया गया है, इसलिए वास्तव में इसके खिलाफ कुछ भी नहीं है। लघु, स्पष्ट और तेज।
रावल

XOR के मुद्दे को + - ऑपरेटर के उपयोग से बचा जा सकता है, लेकिन फिर भी मुझे सबसे अच्छा लगता है a, b = b, a codex = x + yy = xy x = xycode
ashish

22

मैं यह नहीं कहूंगा कि यह स्वैप करने का एक मानक तरीका है क्योंकि यह कुछ अप्रत्याशित त्रुटियों का कारण होगा।

nums[i], nums[nums[i] - 1] = nums[nums[i] - 1], nums[i]

nums[i] पहले संशोधित किया जाएगा और फिर दूसरे चर को प्रभावित करेगा nums[nums[i] - 1]


2
आपको लगभग किसी भी प्रोग्रामिंग भाषा में समस्या है, जो कि स्वैप (ए, बी) का उपयोग करने के लिए सुरक्षित नहीं है, अगर बी या इसके विपरीत पर निर्भर करता है। उदाहरण के लिए, स्वैप (क, ख) के लिए विस्तारित किया जा सकता है: var c=a, a=b, b=c। और फिर, अंतिम असाइनमेंट ab के एड्रेस का मूल्यांकन करने के लिए नए मूल्य का उपयोग करेगा ।
काई पेट्ज़के

1
nums[nums[i] - 1], nums[i] = nums[i], nums[nums[i] - 1]। समस्या का समाधान करेंगे।
बिल चेंग

2
@JacksonKelley दाएं हाथ का मूल्यांकन सुरक्षित है। में nums[i], nums[nums[i] - 1] = nums[nums[i] - 1], nums[i]: समस्या तब है जब अजगर बाएं हाथ का काम करता है, nums[i]बदल दिया जाता है, जो nums[nums[i] - 1]अप्रत्याशित रूप से बदल जाता है। यू पहले यू चाहते हैं पर कल्पना कर सकते हैं nums[1],nums[2] = nums[2],nums[1], लेकिन nums[1] = nums[2]चलाने के बाद , आपके पास nums[2] = nums[1]यू नहीं है , इसके बजाय यू मिला nums[888] = nums[1]
गुओ

5

बहुआयामी सरणियों के लिए काम नहीं करता है, क्योंकि यहां संदर्भ का उपयोग किया जाता है।

import numpy as np

# swaps
data = np.random.random(2)
print(data)
data[0], data[1] = data[1], data[0]
print(data)

# does not swap
data = np.random.random((2, 2))
print(data)
data[0], data[1] = data[1], data[0]
print(data)

Numpy सरणियों के स्वैप स्लाइस भी देखें


यह वास्तव में स्तूप पुस्तकालय की एक विशेष विशेषता (या बग) है।
काई पेट्ज़के

-1

आइकैम द्वारा बताई गई समस्याओं के बारे में जानने के लिए , आप copyमॉड्यूल का उपयोग एक फ़ंक्शन के माध्यम से मानों की उलटी (उलटी) प्रतियों को रखने के लिए कर सकते हैं:

from copy import copy

def swapper(x, y):
  return (copy(y), copy(x))

एक ही समारोह के रूप में lambda:

swapper = lambda x, y: (copy(y), copy(x))

फिर, उन्हें इस तरह वांछित नामों को असाइन करें:

x, y = swapper(y, x)

नोट: यदि आप चाहते थे कि आप deepcopyइसके बजाय आयात / उपयोग कर सकें copy


क्या समस्या है जिसे आप प्रतिलिपि द्वारा हल करने का प्रयास कर रहे हैं?
हनन श्वेतांग


1
लेकिन यह किसी भी समस्या का
वर्णन

-2

आप tuple और XOR स्वैप को जोड़ सकते हैं : x, y = x ^ x ^ y, x ^ y ^ y

x, y = 10, 20

print('Before swapping: x = %s, y = %s '%(x,y))

x, y = x ^ x ^ y, x ^ y ^ y

print('After swapping: x = %s, y = %s '%(x,y))

या

x, y = 10, 20

print('Before swapping: x = %s, y = %s '%(x,y))

print('After swapping: x = %s, y = %s '%(x ^ x ^ y, x ^ y ^ y))

लंबोदर का उपयोग करना :

x, y = 10, 20

print('Before swapping: x = %s, y = %s' % (x, y))

swapper = lambda x, y : ((x ^ x ^ y), (x ^ y ^ y))

print('After swapping: x = %s, y = %s ' % swapper(x, y))

आउटपुट:

Before swapping: x =  10 , y =  20
After swapping: x =  20 , y =  10
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.