Python: Create associative array in a loop - python

I want to create an associative array with values read from a file. My code looks something like this, but its giving me an error saying i can't the indicies must be ints.
Thanks =]
for line in open(file):
x=prog.match(line)
myarray[x.group(1)]=[x.group(2)]

myarray = {} # Declares myarray as a dict
for line in open(file, 'r'):
x = prog.match(line)
myarray[x.group(1)] = [x.group(2)] # Adds a key-value pair to the dict

Associative arrays in Python are called mappings. The most common type is the dictionary.

Because array indices should be an integer
>>> a = [1,2,3]
>>> a['r'] = 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list indices must be integers, not str
>>> a[1] = 4
>>> a
[1, 4, 3]
x.group(1) should be an integer or
if you are using map define the map first
myarray = {}
for line in open(file):
x=prog.match(line)
myarray[x.group(1)]=[x.group(2)]

Related

Python - multiply dictionary values for a list and store the result back in a different dictionary?

I have this problem: two dictionaries, one "dicT" and the other "dictionary". I want to multiply "dicT" for a list (listT) and store the result back in a dictionary, with keys from dicT. Any ideas?
I thought to do the following:
for i in dPdT:
for value in dicT.values():
if not i in dictionary:
dictionary[i] = []
dictionary[i].append(i*value)
But it ends up in the following traceback message:
Traceback (most recent call last):
File "isochore.py", line 197, in <module>
main()
File "isochore.py", line 164, in main
dictionary[i].append(i*value)
TypeError: can't multiply sequence by non-int of type 'float'
Thanks!
Could you give an example of the data and what you expect it to do? What do you expect when you multiply i * value while you think i is also a key so perhaps alphanumeric? That is also the errorcode you are getting.
I tried to guess, please provide actual data because I don't understand what you are trying to do? This is providing all the values in list l multiplied with that value of l so basically **2 ?
oldDictionary = {1: 10,2: 20}
L =[0, 2]
newDictionary = {}
for i in L:
if i in oldDictionary:
newDictionary.update({i: oldDictionary.get(i) * i})
print(newDictionary)
{2: 40}

Remove an element from list and return the result

I want to generate a list which looks like:
['ret-120','ret-115','ret-110',....'ret-5','ret5',....'ret240']
Please note, there's no ret0 element in the list. So I have to remove it from a list populated by range function. I've tried:
['ret'+str(x) for x in list(range(-120,241,5)).remove(0)]
However this gives out an error:
TypeError: 'NoneType' object is not iterable
Is this possible to accomplish with one line of code?
The simplest way to do what you want is to add a conditional inside your list comprehension:
lst = ['cumRet'+str(x) for x in xrange(-120,241,5) if x != 0]
# This part: ^^^^^^^^^
I also removed the unnecessary list creation and changed range->xrange (note that this range->xrange change is Python2 only)
Your NoneType error is because list.remove(index) modifies in-place, so it returns None.
Hence, you are trying to loop [for x in None].
2-line alternate way (with ;)
tmp = list(range(-120,241,5));tmp.remove(0)
['ret'+str(x) for x in list(range(-120,241,5)).remove(0)]
remove() return None
The list remove() method return None, So 'NoneType' object is not iterable.
Demo:
>>> b = list(range(-120,241,5)).remove(0)
>>> b
>>> print b
None
We will create variable of list and then remove 0 from it.
Demo:
>>> tmp = list(range(-120,241,5))
>>> tmp.remove(0)
>>> ['cumRet'+str(x) for x in tmp]
['cumRet-120', 'cumRet-115', 'cumRet-110', 'cumRet-105', 'cumRet-100', 'cumRet-95', 'cumRet-90', 'cumRet-85', 'cumRet-80', 'cumRet-75', 'cumRet-70', 'cumRet-65', 'cumRet-60', 'cumRet-55', 'cumRet-50', 'cumRet-45', 'cumRet-40', 'cumRet-35', 'cumRet-30', 'cumRet-25', 'cumRet-20', 'cumRet-15', 'cumRet-10', 'cumRet-5', 'cumRet5', 'cumRet10', 'cumRet15', 'cumRet20', 'cumRet25', 'cumRet30', 'cumRet35', 'cumRet40', 'cumRet45', 'cumRet50', 'cumRet55', 'cumRet60', 'cumRet65', 'cumRet70', 'cumRet75', 'cumRet80', 'cumRet85', 'cumRet90', 'cumRet95', 'cumRet100', 'cumRet105', 'cumRet110', 'cumRet115', 'cumRet120', 'cumRet125', 'cumRet130', 'cumRet135', 'cumRet140', 'cumRet145', 'cumRet150', 'cumRet155', 'cumRet160', 'cumRet165', 'cumRet170', 'cumRet175', 'cumRet180', 'cumRet185', 'cumRet190', 'cumRet195', 'cumRet200', 'cumRet205', 'cumRet210', 'cumRet215', 'cumRet220', 'cumRet225', 'cumRet230', 'cumRet235', 'cumRet240']
>>>
Exception Handling:
Best practice to do Exception Handling when we went to remove element from the list because if element not present in the list then it will raise ValueError exception.
Demo:
>>> l = [4,6,8]
>>> l.remove(3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list
>>>
>>> try:
... l.remove(3)
... except ValueError:
... print "List not contains remove element."
...
List not contains remove element.
>>>
The problem is that the list.remove() method changes the list in-place and effectively returns None, but you can skip x when it's zero like this:
['ret'+str(x) for x in range(-120, 241, 5) if x]
If you're using Python 2, range() could be changed to xrange() which would avoid creating a temporary list of all the integer values.

convert a list of strings to a list of numbers?

I would like to convert a list of following strings into integers:
>>> tokens
['2', '6']
>>> int(tokens)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: int() argument must be a string or a number, not 'list'
Other than writing a for loop to convert each member of the list tokens, is there a better way to do that? Thanks!
Just use list comprehension:
[int(t) for t in tokens]
Alternatively map the int over the list
map(int, tokens)
However map is changed in python3, so it creates an instance of the map and you would have to cast that back into a list if you want the list.
i = iter(list)
while i.next != None:
print int(i.next())

"Can only iterable" Python error

Hello my fellow programmers.
I am a fairly new programmer, and now I am facing a great predicament. I am getting the error:
can only assign an iterable
Firstly I don't know what that means.
Secondly I will leave my code for you professionals to critique it:
def num_top(int_lis):
duplic_int_lis = int_lis
int_firs= duplic_int_lis [0]
int_lis[:] = duplic_int_lis [int_firs]
Basically I am trying to find the [0] element in the list and then using that int as an index position to find the integer at that index position.
int_lis[:] = duplic_int_lis [int_firs] means assign all the items of duplic_int_lis [int_firs] to int_lis, so it expects you to pass an iterable/iterator on the RHS.
But in your case you're passing it an non-iterable, which is incorrect:
>>> lis = range(10)
>>> lis[:] = range(5)
>>> lis #all items of `lis` replaced with range(5)
[0, 1, 2, 3, 4]
>>> lis[:] = 5 #Non-iterable will raise an error.
Traceback (most recent call last):
File "<ipython-input-77-0704f8a4410d>", line 1, in <module>
lis[:] = 5
TypeError: can only assign an iterable
>>> lis[:] = 'foobar' #works for any iterable/iterator
>>> lis
['f', 'o', 'o', 'b', 'a', 'r']
As you cannot iterate over an integer, hence the error.
>>> for x in 1: pass
Traceback (most recent call last):
File "<ipython-input-84-416802313c58>", line 1, in <module>
for x in 1:pass
TypeError: 'int' object is not iterable
The RHS of a slice-assignment must be an iterable, not a scalar. Consider slice-deleting and then appending instead.
An iterable is a thing with multiple items that you can iterate through (for example: take the 1st value do something, then the 2nd do something, etc...) Lists, dictionaries, tuples, strings have several items in them and can be used as iterables. As a counterexample: number types don't qualify as iterable.
Remember that computers count from #0 so: if you want the first value of a list you can use
my_list[0]
before you go further I would suggest watching this video about looping. https://www.youtube.com/watch?v=EnSu9hHGq5o

Python: how resolve TypeError: an integer is required in a loop

I have a list Dsr
>>> Dsr
[59.10346189206572, 40.4211078871491, 37.22898098099725]
type(Dsr)
<type 'list'>
I need to calculate the max value and divide each element of the list for this value
dmax = numpy.max(Dsr)
RPsr = []
for p in xrange(Dsr):
RPsr.append(float(Dsr[p]/dmax))
I have the following questions:
1) when i run this loop i got thie error message:
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
TypeError: an integer is required
2) is it possible to convert the loop in a most elegant list comprehension?
You're getting the exception because xrange() takes an int and not a list. You need to use len():
for p in xrange(len(Dsr)):
^^^
Since you're already using NumPy, my advice would be to rewrite the whole thing like so:
In [7]: Dsr = numpy.array([59.10346189206572, 40.4211078871491, 37.22898098099725])
In [8]: Dsr / Dsr.max()
Out[8]: array([ 1. , 0.68390423, 0.6298951 ])
If I understood you correctly, you need this:
>>> dsr = [59.10346189206572, 40.4211078871491, 37.22898098099725]
>>> the_max = max(dsr)
>>> [i/the_max for i in dsr]
[1.0, 0.6839042349323938, 0.6298950990211796]
Presumably you want to iterate over the actual list. You don't use xrange for that:
for p in Dsr:
RPsr.append(float(p/dmax))
And you're correct that a list comprehension is the simpler way:
RPsr = [p/dmax for p in Dsr]

Categories

Resources