Strange error happening.
I know of the issue with trying to cast strings with decimals directly into ints:
int(float('0.0'))
works, while
int('0.0')
does not. However, I'm still getting an error that I can't seem to figure out:
field = line.strip().split()
data[k,:] = [int(float(k)) for k in field[1:]]
ValueError: invalid literal for long() with base 10: '0.0'
Any ideas what could be happening here? The script seems to be thinking it's a cast to long instead of float. Any way to convince it otherwise?
Thanks in advance!
EDIT: the data line is of the form:
'c1c9r2r8\t0.0\t3.4\t2.1\t9.0\n'
It appears that what is happening is that the list comprehension is polluting your namespace.
eg.
k = 0
[k for k in range(10)]
After executing the above code in python 2.x the value of k will be 9 (the last value that was produced by range(10)).
I'll simplify your code to show you what is happening.
>>> l = [None, None, None]
>>> k = 0
>>> l[k] = [k for k in range(3)]
>>> print k, l
2 [None, None, [0, 1, 2]]
You see that l[k] evaluated to l[2] rather than l[0]. To avoid this namespace pollution either do not use the same variable names in a list comprehension as you do in the outer code, or use python 3.x where inner variables of list comprehensions no longer escape to the outer code.
For python 2.x your code should be modified to be something like:
data[k,:] = [int(float(_k)) for _k in field[1:]]
>>> line = 'c1c9r2r8\t0.0\t3.4\t2.1\t9.0\n'
>>> field = line.strip().split()
>>> field
['c1c9r2r8', '0.0', '3.4', '2.1', '9.0']
>>> [int(x) for x in map(float, field[1:])]
[0, 3, 2, 9]
Your error is coming from the left-hand side of the assignment data[k, :] = .... Here you're trying to index a NumPy array (data) with a string (k). NumPy tries to do an implicit conversion of that string to a usable integer index, and fails. For example:
>>> import numpy as np
>>> data = np.arange(12).reshape(3, 4)
>>> data['3.4', :] = 6
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for long() with base 10: '3.4'
Use an integer instead of a string here, and the problem should go away.
Related
I have a list with 1550500 numbers, and all of them with quotes.
Example: list('100', '150', '200', '250') etc...
I need to sum all the numbers, but before that I need to convert it to INT.
List Name: trip_list
My code:
mean_tripstr = str(trip_list)
mean_trip = [int(x) for x in mean_tripstr]
print(type(mean_trip))
Error message:
Traceback (most recent call last):
File "projeto1.py", line 235, in <module>
mean_trip = [int(x) for x in mean_tripstr]
File "projeto1.py", line 235, in <listcomp>
mean_trip = [int(x) for x in mean_tripstr]
ValueError: invalid literal for int() with base 10: '['
What am I doing wrong? I am new to coding...
Python has a map function, this takes a function and an iterable. There is also the sum function, which returns the sum of an iterable.
You can use this:
sum(map(int(trip_list))
Note that the map function does not return a list, it returns a generator. To convert it to a list, use
list(sum(map(int, trip_list)))
(this may take a while as it requires iterating over the entire list, and yours is quite long).
The error with your code is converting your list to a string, that is,
>>> my_list = ["5", "6"]
>>> my_list_str = str(my_list)
>>> my_list_str
"['5', '6']"
>>> type(my_list_str)
<class 'str'>
>>> type(my_list)
<class 'list'>
So when you try to iterate over the string, the first x is [ which is not a number (thus the exception).
As a sidenote, using list(map(int, a_list)) is faster than [int(i) for i in a_list]
>>> c1 = "list(map(int, a_list))"
>>> c2 = "[int(i) for i in a_list]"
>>> s = "a_list = [str(i) for i in range(1000)]"
>>> import timeit
>>> timeit.timeit(c1, setup=s, number=10000)
1.9165708439999918
>>> >>> timeit.timeit(c2, setup=s, number=10000)
2.470973639999997
You have to convert each element to int:
mean_tripstr = map(str,trip_list)
mean_trip = list(map(int,mean_tripstr))
The code above uses a generator, what is more efficient in cases when you just have to iterate in a list. The last line convert to a list again properly.
But, as you said, if you already have a list of strings, you can just do:
mean_trip = list(map(int,trip_list))
If you know numpy, you can do too:
import numpy as np
trip_list = np.array(trip_list)
mean_trip = trip_list.astype(np.int)
I have the following list (the actual file is much larger and complex)
a = [[['3x5'], ['ff']], [['4x10'], ['gg']]]
I would like to use the split functionality for the first element in the list and get the value in which appears after "x". The final results should be 5 and 10 in this case. I tried to use split in this format
for line in a:
print str(line[0]).split("x")[1]
but the output is
5']
10']
I know I can easily manipulate the output to get 5 and 10 but what is the correct way of using split in this case?
And I am interested in using split for specific element of a list (first elements in this case).
You need to dive one level deeper, and dont use str() on the list.
>>> a = [[['3x5'], ['ff']], [['4x10'], ['gg']]]
>>> for y in a:
... if 'x' in y[0][0]:
... print y[0][0].split('x')[-1]
5
10
You shouldn't the list to a string object, however, you can do it use:
>>> [i[0][0].split('x')[1] for i in a]
['5', '10']
I think you also want to convert the output to int object, then you can simply add an int() like below:
>>> [int(i[0][0].split('x')[1]) for i in a]
[5, 10]
However, if you don't need save the output into a list, but print it out instead, you can just use the same code, but write another version:
a = [[['3x5'], ['ff']], [['4x10'], ['gg']]]
for i in a:
print(i[0][0].split('x')[1])
Output:
5
10
Remember that my code will failed (raise IndexError: list index out of range) when a is... For example [[['3x5'], ['ff']], [['kk'], ['gg']]] (the first element in one of the sublists isn't in format like '3x5').
However, a simple if can fix this:
>>> a = [[['3x5'], ['ff']], [['kk'], ['gg']]]
>>> [int(i[0][0].split('x')[1]) for i in a]
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<input>", line 1, in <listcomp>
IndexError: list index out of range
>>> [int(i[0][0].split('x')[1]) for i in a if 'x' in i[0][0]]
[5]
Or even better, use RegEx to check, which can avoid something like a = [[['3x5'], ['ff']], [['xxxxxxx'], ['gg']]]:
>>> import re
>>> a = [[['3x5'], ['ff']], [['xxxxxxx'], ['gg']]]
>>> [int(i[0][0].split('x')[1]) for i in a if re.search(r'\d+x\d+', i[0][0])]
[5]
Another way, if you don't want import re:
>>> [int(i[0][0].split('x')[1]) for i in a
... if all(j.isdigit() for j in i[0][0].split('x'))]
[5]
I have a python tuple like so,
((1420455415000L, 2L), (1420545729000L, 3L), (1420653453000L, 2L))
I want to convert it into this format:
[[1420455415000, 2], [1420545729000, 3], [1420653453000, 2]]
Please note that I also want to remove the 'L' that is automatically removed when I convert this tuple to dict. I have converted the tuple of tuples to list using :
def listit(t):
return list(map(listit, t)) if isinstance(t, (list, tuple)) else t
but the L still remains. That is a problem because I am sending the data to Javascript
How can I do this?
If you're passing the data to JavaScript, you can do this trivially with the json (JavaScript Object Notation) module:
>>> import json
>>> json.dumps(((1420455415000L, 2L), (1420545729000L, 3L), (1420653453000L, 2L)))
'[[1420455415000, 2], [1420545729000, 3], [1420653453000, 2]]'
To get the output in your question you could use
t = ((1420455415000L, 2L), (1420545729000L, 3L), (1420653453000L, 2L))
l = [map(int,x) for x in t]
The conversion from long to int would only work if the value was less than or equal to sys.maxint. Otherwise it will stay as a long. The conversion is not necessary though as the L is only really denoting the type and not the value.
If you are passing it to javascript, the conversion to json makes more sense.
'L' merely indicates variable's type, in this case Long Integer. Hence whatever the way you are sending the data it will behave as an Int.
That said, if you really don't want to see that 'L' you would need to change the type into integer with simple int():
L denotes that the numbers is of type long , if you are 100% sure that the number would be less than the limit that int can handle (in python , which means on conversion to int it would remain int and not revert back to long , which can happen if the number is very very large), then you can simply convert by using int(num) . But please note, L is just an internal representation and it would not show up when the number is converted to string (or printed, for which it is internally converted to string) , it will only show up when using repr() .
Example -
>>> i = 2L
>>> i
2L
>>> int(i)
2
>>> print i
2
>>> str(i)
'2'
>>> i
2L
In your case, to convert longs to int inside a list use -
>>> l = [1L , 2L , 3L]
>>> print l
[1L, 2L, 3L]
>>> l = map(int, l)
>>> l
[1, 2, 3]
>>> print l
[1, 2, 3]
If its possible that the lists have sublists, use a recursive function such as -
def convertlist(l):
if isinstance(l , (list, tuple)):
return list(map(convertlist, l))
elif isinstance(l , long):
return int(l)
else:
return l
>>> l = [1L , 2L , [3L]]
>>> convertlist(l)
[1, 2, [3]]
The playSound function is taking a list of integers, and is going to play a sound for every different number. So if one of the numbers in the list is 1, 1 has a designated sound that it will play.
def userNum(iterations):
myList = []
for i in range(iterations):
a = int(input("Enter a number for sound: "))
myList.append(a)
return myList
print(myList)
def playSound(myList):
for i in range(myList):
if i == 1:
winsound.PlaySound("SystemExit", winsound.SND_ALIAS)
I am getting this error:
TypeError: 'list' object cannot be interpreted as an integer
I have tried a few ways to convert the list to integers. I am not too sure what I need to change. I am sure that there is a more efficient way of doing this. Any help would be very greatly appreciated.
Error messages usually mean precisely what they say. So they must be read very carefully. When you do that, you'll see that this one is not actually complaining, as you seem to have assumed, about what sort of object your list contains, but rather about what sort of object it is. It's not saying it wants your list to contain integers (plural)—instead, it seems to want your list to be an integer (singular) rather than a list of anything. And since you can't convert a list into a single integer (at least, not in a way that is meaningful in this context) you shouldn't be trying.
So the question is: why does the interpreter seem to want to interpret your list as an integer? The answer is that you are passing your list as the input argument to range, which expects an integer. Don't do that. Say for i in myList instead.
For me i was getting this error because i needed to put the arrays in paratheses. The error is a bit tricky in this case...
ie. concatenate((a, b)) is right
not concatenate(a, b)
hope that helps.
The error is from this:
def playSound(myList):
for i in range(myList): # <= myList is a list, not an integer
You cannot pass a list to range which expects an integer. Most likely, you meant to do:
def playSound(myList):
for list_item in myList:
OR
def playSound(myList):
for i in range(len(myList)):
OR
def playSound(myList):
for i, list_item in enumerate(myList):
range is expecting an integer argument, from which it will build a range of integers:
>>> range(10)
range(0, 10)
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
Moreover, giving it a list will raise a TypeError because range will not know how to handle it:
>>> range([1, 2, 3])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object cannot be interpreted as an integer
>>>
If you want to access the items in myList, loop over the list directly:
for i in myList:
...
Demo:
>>> myList = [1, 2, 3]
>>> for i in myList:
... print(i)
...
1
2
3
>>>
remove the range.
for i in myList
range takes in an integer. you want for each element in the list.
You should do this instead:
for i in myList:
# etc.
That is, remove the range() part. The range() function is used to generate a sequence of numbers, and it receives as parameters the limits to generate the range, it won't work to pass a list as parameter. For iterating over the list, just write the loop as shown above.
since it's a list it cannot be taken directly into range function as the singular integer value of the list is missing.
use this
for i in range(len(myList)):
with this, we get the singular integer value which can be used easily
In playSound(), instead of
for i in range(myList):
try
for i in myList:
This will iterate over the contents of myList, which I believe is what you want. range(myList) doesn't make any sense.
def userNum(iterations):
myList = []
for i in range(iterations):
a = int(input("Enter a number for sound: "))
myList.append(a)
print(myList) # print before return
return myList # return outside of loop
def playSound(myList):
for i in range(len(myList)): # range takes int not list
if i == 1:
winsound.PlaySound("SystemExit", winsound.SND_ALIAS)
n=input().split()
ar=[]
for i in n:
if i not in ar:
ar.append(i)
print(*ar)
We usually pass string as a integer... for that we have to type "n"
when we facing like this error:
TypeError: st object cannot be interpreted as an st
it usually because we use X instead len(X) in for loops
#error
for i in range(df.index):
pass
#currect
for i in range( len(df.index) ):
pass
list cannot be interpreted as an integer when using range
for i in range(list): -> will not work
for i in list: -> will work
This question already has answers here:
Understanding slicing
(38 answers)
Why can't I use a list as a dict key in python?
(11 answers)
Closed 4 months ago.
I'm trying to take a file that looks like this:
AAA x 111
AAB x 111
AAA x 112
AAC x 123
...
And use a dictionary to so that the output looks like this
{AAA: ['111', '112'], AAB: ['111'], AAC: [123], ...}
This is what I've tried
file = open("filename.txt", "r")
readline = file.readline().rstrip()
while readline!= "":
list = []
list = readline.split(" ")
j = list.index("x")
k = list[0:j]
v = list[j + 1:]
d = {}
if k not in d == False:
d[k] = []
d[k].append(v)
readline = file.readline().rstrip()
I keep getting a TypeError: unhashable type: 'list'. I know that keys in a dictionary can't be lists but I'm trying to make my value into a list not the key. I'm wondering if I made a mistake somewhere.
As indicated by the other answers, the error is to due to k = list[0:j], where your key is converted to a list. One thing you could try is reworking your code to take advantage of the split function:
# Using with ensures that the file is properly closed when you're done
with open('filename.txt', 'rb') as f:
d = {}
# Here we use readlines() to split the file into a list where each element is a line
for line in f.readlines():
# Now we split the file on `x`, since the part before the x will be
# the key and the part after the value
line = line.split('x')
# Take the line parts and strip out the spaces, assigning them to the variables
# Once you get a bit more comfortable, this works as well:
# key, value = [x.strip() for x in line]
key = line[0].strip()
value = line[1].strip()
# Now we check if the dictionary contains the key; if so, append the new value,
# and if not, make a new list that contains the current value
# (For future reference, this is a great place for a defaultdict :)
if key in d:
d[key].append(value)
else:
d[key] = [value]
print d
# {'AAA': ['111', '112'], 'AAC': ['123'], 'AAB': ['111']}
Note that if you are using Python 3.x, you'll have to make a minor adjustment to get it work properly. If you open the file with rb, you'll need to use line = line.split(b'x') (which makes sure you are splitting the byte with the proper type of string). You can also open the file using with open('filename.txt', 'rU') as f: (or even with open('filename.txt', 'r') as f:) and it should work fine.
Note:
This answer does not explicitly answer the asked question. the other answers do it. Since the question is specific to a scenario and the raised exception is general, This answer points to the general case.
Hash values are just integers which are used to compare dictionary keys during a dictionary lookup quickly.
Internally, hash() method calls __hash__() method of an object which are set by default for any object.
Converting a nested list to a set
>>> a = [1,2,3,4,[5,6,7],8,9]
>>> set(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
This happens because of the list inside a list which is a list which cannot be hashed. Which can be solved by converting the internal nested lists to a tuple,
>>> set([1, 2, 3, 4, (5, 6, 7), 8, 9])
set([1, 2, 3, 4, 8, 9, (5, 6, 7)])
Explicitly hashing a nested list
>>> hash([1, 2, 3, [4, 5,], 6, 7])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> hash(tuple([1, 2, 3, [4, 5,], 6, 7]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> hash(tuple([1, 2, 3, tuple([4, 5,]), 6, 7]))
-7943504827826258506
The solution to avoid this error is to restructure the list to have nested tuples instead of lists.
You're trying to use k (which is a list) as a key for d. Lists are mutable and can't be used as dict keys.
Also, you're never initializing the lists in the dictionary, because of this line:
if k not in d == False:
Which should be:
if k not in d == True:
Which should actually be:
if k not in d:
The reason you're getting the unhashable type: 'list' exception is because k = list[0:j] sets k to be a "slice" of the list, which is logically another, often shorter, list. What you need is to get just the first item in list, written like so k = list[0]. The same for v = list[j + 1:] which should just be v = list[2] for the third element of the list returned from the call to readline.split(" ").
I noticed several other likely problems with the code, of which I'll mention a few. A big one is you don't want to (re)initialize d with d = {} for each line read in the loop. Another is it's generally not a good idea to name variables the same as any of the built-ins types because it'll prevent you from being able to access one of them if you need it — and it's confusing to others who are used to the names designating one of these standard items. For that reason, you ought to rename your variable list variable something different to avoid issues like that.
Here's a working version of your with these changes in it, I also replaced the if statement expression you used to check to see if the key was already in the dictionary and now make use of a dictionary's setdefault() method to accomplish the same thing a little more succinctly.
d = {}
with open("nameerror.txt", "r") as file:
line = file.readline().rstrip()
while line:
lst = line.split() # Split into sequence like ['AAA', 'x', '111'].
k, _, v = lst[:3] # Get first and third items.
d.setdefault(k, []).append(v)
line = file.readline().rstrip()
print('d: {}'.format(d))
Output:
d: {'AAA': ['111', '112'], 'AAC': ['123'], 'AAB': ['111']}
The reason behind this is the list contains list of values. Like:
a = [[1,2],[1,2],[3,4]]
And this won't work with something like this:
list(set(a))
To fix this you can transform the interior list to tuple, like :
a = [(1,2),(1,2),(3,4)]
This will work !
The TypeError is happening because k is a list, since it is created using a slice from another list with the line k = list[0:j]. This should probably be something like k = ' '.join(list[0:j]), so you have a string instead.
In addition to this, your if statement is incorrect as noted by Jesse's answer, which should read if k not in d or if not k in d (I prefer the latter).
You are also clearing your dictionary on each iteration since you have d = {} inside of your for loop.
Note that you should also not be using list or file as variable names, since you will be masking builtins.
Here is how I would rewrite your code:
d = {}
with open("filename.txt", "r") as input_file:
for line in input_file:
fields = line.split()
j = fields.index("x")
k = " ".join(fields[:j])
d.setdefault(k, []).append(" ".join(fields[j+1:]))
The dict.setdefault() method above replaces the if k not in d logic from your code.
python 3.2
with open("d://test.txt") as f:
k=(((i.split("\n"))[0].rstrip()).split() for i in f.readlines())
d={}
for i,_,v in k:
d.setdefault(i,[]).append(v)