पायथन में वस्तुओं की एक सूची बनाना


83

मैं एक पायथन स्क्रिप्ट बनाने की कोशिश कर रहा हूं जो कई डेटाबेस खोलती है और उनकी सामग्री की तुलना करती है। उस स्क्रिप्ट को बनाने की प्रक्रिया में, मैं एक सूची बनाने में समस्या में चला गया हूं जिसकी सामग्री ऐसी वस्तुएं हैं जिन्हें मैंने बनाया है।

मैंने इस पोस्टिंग के लिए इसकी नंगे हड्डियों के लिए कार्यक्रम को सरल बनाया है। पहले मैं एक नया वर्ग बनाता हूं, इसका एक नया उदाहरण बनाता हूं, इसे एक विशेषता प्रदान करता हूं और फिर इसे एक सूची में लिखता हूं। फिर मैं उदाहरण के लिए एक नया मान प्रदान करता हूं और फिर से इसे एक सूची में लिखता हूं ... और फिर और फिर ...

समस्या यह है, यह हमेशा एक ही वस्तु है इसलिए मैं वास्तव में बस आधार वस्तु बदल रहा हूं। जब मैं सूची को पढ़ता हूं, तो मुझे एक ही वस्तु का बार-बार दोहराव मिलता है।

तो आप एक लूप के भीतर वस्तुओं को सूची में कैसे लिखते हैं?

यहाँ मेरा सरलीकृत कोड है

class SimpleClass(object):
    pass

x = SimpleClass
# Then create an empty list
simpleList = []
#Then loop through from 0 to 3 adding an attribute to the instance 'x' of SimpleClass
for count in range(0,4):       
    # each iteration creates a slightly different attribute value, and then prints it to
# prove that step is working
# but the problem is, I'm always updating a reference to 'x' and what I want to add to
# simplelist is a new instance of x that contains the updated attribute

x.attr1= '*Bob* '* count
print "Loop Count: %s Attribute Value %s" % (count, x.attr1)
simpleList.append(x)

print '-'*20
# And here I print out each instance of the object stored in the list 'simpleList'
# and the problem surfaces.  Every element of 'simpleList' contains the same      attribute value

y = SimpleClass
print "Reading the attributes from the objects in the list"
for count in range(0,4):
    y = simpleList[count]
    print y.attr1

तो मैं कैसे (अपील, विस्तार, नकल या जो भी) simpleList के तत्वों को शामिल करता हूं ताकि प्रत्येक प्रविष्टि में एक ही इंगित करने के बजाय ऑब्जेक्ट का एक अलग उदाहरण हो?


2
मेरा सुझाव है कि आप काउंटर के बजाय पुनरावृत्तियों का उपयोग करें: "सरल में आइटम के लिए:" बहुत बेहतर दिखता है।
मापद

जवाबों:


70

आप एक मूलभूत गलतफहमी को प्रदर्शित करते हैं।

आपने कभी भी SimpleClass का उदाहरण नहीं बनाया, क्योंकि आपने इसे कॉल नहीं किया था।

for count in xrange(4):
    x = SimpleClass()
    x.attr = count
    simplelist.append(x)

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

simplelist = [SimpleClass(count) for count in xrange(4)]

2
अजगर 3.x के लिए उपलब्ध नहीं है - xrange () दुर्गंध अब समर्थित नहीं है।
r3t40

3
@TitPoplatnik बस श्रेणी () के लिए xrange () को बदलें।
eXPRESS

@ironfroggy से वह इंडेक्स प्राप्त करना संभव है, जिस पर ऑब्जेक्ट को क्लास के भीतर से स्टोर किया जाता है। यह कहें कि यदि क्लास A किसी सूची में
वें

55

किसी वर्ग के अलग-अलग उदाहरणों के साथ एक सूची भरने के लिए, आप सूची की घोषणा में लूप का उपयोग कर सकते हैं। * प्रत्येक प्रतिलिपि को उसी उदाहरण से गुणा करेगा।

instancelist = [ MyClass() for i in range(29)]

और फिर सूची के सूचकांक के माध्यम से उदाहरणों तक पहुंचें।

instancelist[5].attr1 = 'whamma'

3
बेहतर हो: instancelist = [MyClass () for _ in रेंज (29)]
tutormike

11

हर बार सिंपलक्लास ऑब्जेक्ट को फिर से बनाना आवश्यक नहीं होना चाहिए, जैसा कि कुछ सुझाव दे रहे हैं, यदि आप इसे केवल इसके गुणों के आधार पर आउटपुट डेटा के लिए उपयोग कर रहे हैं। हालाँकि, आप वास्तव में कक्षा का एक उदाहरण नहीं बना रहे हैं; आप केवल क्लास ऑब्जेक्ट के लिए एक संदर्भ बना रहे हैं। इसलिए, आप सूची में (उदाहरण विशेषता के बजाय), उसी वर्ग विशेषता का संदर्भ जोड़ रहे हैं।

के बजाय:

x = SimpleClass

आप की जरूरत है:

x = SimpleClass()

7
x = SimpleClass() है वस्तु हर बार पुनः।
नील

5

हर बार एक नया उदाहरण बनाएं, जहां प्रत्येक नए उदाहरण में एक ही उदाहरण की स्थिति को लगातार संशोधित करने के बजाय सही स्थिति हो।

वैकल्पिक रूप से, मूल के बजाय प्रत्येक चरण में ऑब्जेक्ट की स्पष्ट रूप से बनाई गई प्रतिलिपि ( इस पृष्ठ पर संकेत का उपयोग करके ) को स्टोर करें ।


3

यदि मैं आपके प्रश्न को सही ढंग से समझता हूं, तो आप किसी ऑब्जेक्ट की गहरी कॉपी निष्पादित करने का तरीका पूछते हैं। Copy.deepcopy का उपयोग करने के बारे में क्या?

import copy

x = SimpleClass()

for count in range(0,4):
  y = copy.deepcopy(x)
  (...)
  y.attr1= '*Bob* '* count

डीपकोपी पूरे ऑब्जेक्ट की एक पुनरावर्ती प्रतिलिपि है। अधिक संदर्भ के लिए, आप अजगर प्रलेखन पर एक नज़र डाल सकते हैं: https://docs.python.org/2/library/cn.html


2
किसी ऑब्जेक्ट का पुन: उपयोग - गहरी प्रतिलिपि या क्लोन - एक सामान्य n00b भ्रम है। कभी-कभी आप सवाल का जवाब देने के लिए प्रकट नहीं कर सकते हैं; कभी-कभी आपको उस प्रश्न का उत्तर देना होगा जो उन्हें पूछना चाहिए था।
एस.लॉट

3

मुझे लगता है कि यह केवल यह दर्शाता है कि आप क्या हासिल करने की कोशिश कर रहे हैं:

# coding: utf-8

class Class():
    count = 0
    names = []

    def __init__(self,name):
        self.number = Class.count
        self.name = name
        Class.count += 1
        Class.names.append(name)

l=[]
l.append(Class("uno"))
l.append(Class("duo"))
print l
print l[0].number, l[0].name
print l[1].number, l[1].name
print Class.count, Class.names

ऊपर दिए गए कोड को चलाएं और आप प्राप्त करें: -

[<__main__.Class instance at 0x6311b2c>, 
<__main__.Class instance at 0x63117ec>]
0 uno
1 duo
2 ['uno', 'duo']
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.