.index() generates AttributeError: 'dict_values' object has no attribute 'index' - python

I'm trying to rewrite this Python2 code to Python3 accepted syntax. The .index() methods generates the following error:
AttributeError: 'dict_values' object has no attribute 'index'
This is because .index() is no valid syntax in Python3. I've read that a list should be used to work around the problem, but I can't figure out how to do it. Anyone any idea how to work around the problem?
words1 = [self._word_to_id.keys()[self._word_to_id.values().index(data_x[index])] for index in range(len(puncts) - 1)]
indices = [i for i, w in enumerate(words1) if w in PUNCTUATIONS]
for i in indices:
words1[i], words1[i-1] = words1[i-1], words1[i]
words2 = [self._word_to_id.keys([self._word_to_id.values().index(data_x[index])] for index in range(len(puncts) - 1, len(data_x))]
all_words = words1 + [puncts[-1]] + words2
content = ' '.join(all_words)
min_step = len(puncts)

You are calling self._word_to_id.values() which returns the class dict_values and not list. dict_values does not inherit from list and does not have the index method because of that.
You need to convert your dictionary values into a list to use the index function. Try this:
list(self._word_to_id.values()).index(data_x[index])

words1 = [list(self._word_to_id.keys())[list(self._word_to_id.values()).index(data_x[index])] for index in range(len(puncts) - 1)]

Related

Attribute error even after adding the enumerate

I keep getting Attributeerror such as 'tuple' object has no attribute 'split'.
At first I did not have enumerate in this code, and I got attribute error saying that 'int' object has no attribute 'split'. So added te enumerate referencing this question.
But i sill get the same error.
enterreleased_date = []
released_country = []
released_year = []
for i in enumerate(df['released']):
date = i.split("(")[0]
country = i.split("(")[1].replace(')','')
released_date.append(date)
released_country.append(country)
df['released_country'] = released_country
df['released_date'] = released_date
df['released_date'] = pd.to_datetime(df['released_date'])
df['released_year'] = df['released_date'].dt.year
df['released_month'] = df['released_date'].dt.month
#drop the unneccessary columns --yearcorrect was created by accident so we'll delete that as well
df.drop(['year','released','released_date','yearcorrect'], axis=1, inplace=True)
df['logbudget'] = np.log(df['budget'])
df['loggross'] = np.log(df['gross'])
df.head(3) code here
When you are calling this:
for i in enumerate(df['released']):
enumerate(x) return a tuple object of 2 elements. 1st the number i of sample in x and 2nd the i-th element in x itself. What do you get as i then is a tuple of the two elements per iteration. If you are using .split for a string, you need to write:
for i, string in enumerate(df['released']):
So now you get the two elements inside the tuple of each iteration. And then you can use split() as: string.split().
Try:
for i in enumerate(df['released']):
print(i)
And:
for i, string in enumerate(df['released']):
print(i)
print(string )
To see the difference.
EDITED: As #flakes suggests, it seems like you don't actually need to use enumerate. As for-loops in python are wiser than other languages and they iterate over elements in arrays/lists/etc and don't need a number to help them. for elem in df['released']: would be enough.

Access list from a function

I have created a function which returns a list
def GetAddressContainer(obj,obj1):
mylist = list()
for i in test['adresss']:
addresscotainer = i[id]
return mylist(addresscontainer)
When i call the function -
UkContainer = GetAddressContainer(Postcode,Country)
i get the following error message:
TypeError: 'list' object is not callable in python
Any ideas why i am getting this error and what i would have to update?
The problems seem to be in
return mylist(addresscontainer)
You using parentheses on the list and therefore calling it as a function, that's why you get the error. Without any more code I not entirely sure what to replace it with though.
Issues
The line mylist = list() basically creates an empty list which you can use to store any values. In the code mylist is being called (using (...)) which does not make sense in python since mylist is not a function.
Another issue with the code is that the value of addresscontainer is never being inserted into mylist.
Possible Solutions
So, as per your problem, either of the following solutions can be used:
Append addresscontainer into mylist iteratively within the for loop:
for i in test['adress']:
addresscontainer = i[id]
mylist.append(addresscontainer) # Inserts the value at the end of list
return mylist # Returns the list
[RECOMMENDED] Use list comprehension:
def GetAddressContainer(...):
return [i[id] for i in test['adress']] # Build list using "List Comprehension"
Replace mylist(addresscontainer) with list(addresscontainer) code.
Only list word could be a callable function because it defines a class of any list. And mylist = list() will be an instance of an abstract list, then, not callable.
change mylist = list() to mylist = []
it will create an empty list instead of a list object.
and you are not appending anything to the list.

Adding contents of a queryset to a list in Django/Python

I'm pretty new to Django. I'm trying to iterate over my queryset and add the field which happens to be called 'id' of each to a new list.
My end result should be a list looking something like this (for example): [1, 2, 3, 7, 10]
My code looks like this:
my_list = []
for foo in bar:
number = foo.id
my_list += number
I'm getting this error: TypeError: 'long' object is not iterable
The type of foo.id is long
I have tried changing the foo.id to an int or str using:
number = str(number)
Have also tried the solution here (I'm using Python 2.7): TypeError: 'long' object is not iterable but I get this: AttributeError: 'QuerySet' object has no attribute 'iteritems'
Any help much appreciated!
As for why your code raises an error: you'd have to use my_list.append(number) (my_list += anything is a shortcut for my_list.extends(anything) which expects an iterable and will append all values from this iterable to my_list).
Now actually, the pythonic way here would be to use a list comprehension instead, ie :
my_list = [foo.id for foo in bar]
But since it's about a Django queryset, the right solution is to use QuerySet.values_list():
bar = MyModel.objects.values_list("id", flat=True)
which will result in bar being an iterable over your queryset's 'id' values. And if you really need a list, then you just have to pass bar to the list constructor:
my_list = list(bar)
It is bad practice to iterate over queryset to get id of each object. I suggest to use values_list() like. which will give you list of id of each object in queryset.
ids = bar.values_list('id', flat=True)

'int' object and 'float' object not callable error

I have a post request returning a list: [u'2']
I am trying to extract the number and turn it into and integer but I keep getting either 'float' object not callable or 'int' object not callable.
Here is what I have tried so far:
speed = [u'2']
strSpeed = speed[3]
intSpeed = int(strSpeed)
and
strSpeed = speed[3]
intSpeed = float(strSpeed)
and
strSpeed = speed[3]
intSpeed = int(float(strSpeed))
It seems that I can do:
print float(strSpeed)
but I can't return it.
Any ideas?
You have a list of Unicode strings:
>>> speed
[u'2']
Obtain the first item from the list, it's a Unicode string:
>>> speed[0]
u'2'
Convert this string to an integer:
>>> int(speed[0])
2
Here you are.
Your speed variable has only a single item, so you can only access index [0]
>>> int(speed[0])
2
>>> speed[0]
'2'
The u is a prefix to declare a unicode string literal. So speed is just a list with a single unicode string.
Not sure exactly what you are trying to do but if you have a list of string items and you want to extract and convert to integters or floats, you could do the following:
stringlist = ["1", "2", "3.2"]
intlistitem = int(stringlist[0])
print(intlistitem)
floatlistitem = float(stringlist[2])
print(floatlistitem)

Create a list of defaultdict in python

I am doing the following :
recordList=[lambda:defaultdict(str)]
record=defaultdict(str)
record['value']='value1'
record['value2']='value2'
recordList.append(record)
for record in recordList:
params = (record['value'],record['value2'],'31')
i am getting the error :
TypeError: 'function' object is not
subscriptable
what is wrong here ?
recordList=[lambda:defaultdict(str)]
creates a list with a function that returns defaultdict(str). So it's basically equivalent to:
def xy ():
return defaultdict(str)
recordList = []
recordList.append( xy )
As such, when you start your for loop, you get the first element from the list, which is not a list (as all the other elements you push to it), but a function. And a function does not have a index access methods (the ['value'] things).
recordList is a list with 1 element which is a function.
If you replace the first line with
recordList = []
the rest will wor.
you're adding a lambda to recordList, which is of type 'function'. in the for .. loop, you're trying to subscript it (record['value'], record['value2'], etc)
Initialize recordList to an empty list ([]) and it will work.

Categories