Reputation: 537
I'm python newbie and found something difficult while doing some practices.
I have few def functions under a class look like:
Class A(object):
def __init__(self):
self.itemID = []
self.itemlist = []
def add(self, ID, list):
self.itemID.append(ID)
self.itemlist.append(list)
def get_item(self,ID):
self.ID = ID
result = []
for self.ID in self.itemlist:
result.append(self.itemlist)
return result
I'm having problems with "def get_item". Here's an example..
if i do:
A.add('abc', 'bcd')
A.add('abc1', 'bcd1')
A.get_item('abc')
This should return abc, bcd but mine returns [['bcd', 'bcd1'], ['bcd', 'bcd1']]...
Apologise for the long complicated dumb looked codes.... Any feedbacks would be so appreciated.. Thanks
Upvotes: 1
Views: 3489
Reputation: 35079
Your get_item
code is very confused. It overwrites self.ID
, several times, when it should only read it, and the loop appends the entire itemlist (or, rather, the itemlist itself) to the result - and it does this at every iteration. This is why you are seeing such a strange result.
What you are probably thinking of is this:
def get_item(self, ID):
for index in range(self.ID.length):
if self.id[index] == ID:
return self.itemlist[index]
That is: iterate over the indexes of both lists, and when you find the one that has a matching ID at that position in the ID list, return the thing in the corresponding position in itemlist
.
This code can be improved a bit by using Python's built-in functions. For example, you could use zip
- which can take both your lists (ID
and itemlist
), and give you back pairs of corresponding items - so, you have:
def get_item(self, ID):
for id, item in zip(self.ID, self.itemlist):
if id == ID:
return item
But you can get rid of the loop entirely by using list methods - list.index
does the search for you:
def get_item(self, ID):
return self.itemlist[self.ID.index(ID)]
Upvotes: 0
Reputation: 184191
Others have explained how to make it work; I'm going to explain why what you had doesn't work.
The problem here is that Python is doing exactly what you tell it to do:
for self.ID in self.itemlist:
result.append(self.itemlist)
In a loop, set self.ID
to each element of self.itemlist
in order. (By the way, it is entirely unnecessary to use an instance attribute for this since there's no need to keep the ID
when the method is done; you should probably use a local variable here instead.)
Each time through the loop, append a reference to self.itemlist
to the result.
In other words, you are asking for individual items from your self.itemlist
, but not doing anything with the items. All your append operations append the original list, not the current item from the list.
As a result, your method returns a list with as many copies of self.itemlist
as there are elements in it.
Upvotes: 1
Reputation: 6814
your get_item function is absolutely wrong :)
Here's how it should look like:
def get_item(self,ID):
result = []
for x in range(0, len(self.itemID)):
if (self.itemID[x] == ID):
result.append(self.itemlist[x])
return result
Or even better:
def get_item(self, ID):
return [self.itemlist[x] for x in range(0, len(self.itemID) if self.itemID[x] == ID]
Now, if I understand the logic behind your class, you want to be able to retrieve a list of object given a common ID. This can be better done using a dict
class A:
def __init__(self):
self.content = {}
def add(self, ID, object):
list = self.get_item(ID)
list.append(object)
content[ID] = list
def get_item(self, ID):
return content.get(ID, [])
Upvotes: 0
Reputation: 27087
Why not use a dict
?
A = {}
A['abc'] = 'bcd'
A['abc1'] = 'bcd1'
Then, A['abc']
returns 'bcd'
, as you want.
You can access the IDs with A.keys()
and the items A.values()
so you don't lose any functionality.
As @Stals points out in the comments, if you want to retain the order that you add things, you can also use an OrderedDict
.
If you really need more than one item with the same ID, there are various multidict
recipes that might work.
Upvotes: 2