Nested List and For Loop - python

Consider this:
list = 2*[2*[0]]
for y in range(0,2):
for x in range(0,2):
if x ==0:
list[x][y]=1
else:
list[x][y]=2
print list
Result:
[[2,2],[2,2]]
Why doesn't the result be [[1,1],[2,2]]?

Because you are creating a list that is two references to the same sublist
>>> L = 2*[2*[0]]
>>> id(L[0])
3078300332L
>>> id(L[1])
3078300332L
so changes to L[0] will affect L[1] because they are the same list
The usual way to do what you want would be
>>> L = [[0]*2 for x in range(2)]
>>> id(L[0])
3078302124L
>>> id(L[1])
3078302220L
notice that L[0] and L[1] are now distinct

Alternatively to save space:
>>> [[x,x] for x in xrange(1,3)]

Related

Create a list of consequential alphanumeric elements

I have
char=str('DOTR')
and
a=range(0,18)
How could I combine them to create a list with:
mylist=['DOTR00','DOTR01',...,'DOTR17']
If I combine them in a for loop then I lose the leading zero.
Use zfill:
>>> string = "DOTR"
>>> for i in range(0, 18):
... print("DOTR{}".format(str(i).zfill(2)))
...
DOTR00
DOTR01
DOTR02
DOTR03
DOTR04
DOTR05
DOTR06
DOTR07
DOTR08
DOTR09
DOTR10
DOTR11
DOTR12
DOTR13
DOTR14
DOTR15
DOTR16
DOTR17
>>>
And if you want a list:
>>> my_list = ["DOTR{}".format(str(i).zfill(2)) for i in range(18)]
>>> my_list
['DOTR00', 'DOTR01', 'DOTR02', 'DOTR03', 'DOTR04', 'DOTR05', 'DOTR06', 'DOTR07', 'DOTR08', 'DOTR09', 'DOTR10', 'DOTR11', 'DOTR12', 'DOTR13', 'DOTR14', 'DOTR15', 'DOTR16', 'DOTR17']
>>>
You can do it using a list comprehension like so:
>>> mylist = [char+'{0:02}'.format(i) for i in a]
>>> mylist
['DOTR00', 'DOTR01', 'DOTR02', 'DOTR03', 'DOTR04', 'DOTR05', 'DOTR06', 'DOTR07', 'DOTR08', 'DOTR09', 'DOTR10', 'DOTR11', 'DOTR12', 'DOTR13', 'DOTR14', 'DOTR15', 'DOTR16', 'DOTR17']
Simply use list comprehension and format:
mylist = ['DOTR%02d'%i for i in range(18)]
Or given that char and a are variable:
mylist = ['%s%02d'%(char,i) for i in a]
You can, as #juanpa.arrivillaga also specify it as:
mylist = ['{}{:02d}'.format(char,i) for i in a]
List comprehension is a concept where you write an expression:
[<expr> for <var> in <iterable>]
Python iterates over the <iterable> and unifies it with <var> (here i), next it calls the <expr> and the result is appended to the list until the <iterable> is exhausted.
can do like this
char = str('DOTR')
a=range(0,18)
b = []
for i in a:
b.append(char + str(i).zfill(2))
print(b)

With 2 list of strings, trying to find a way to print the string in the same position/order from the opposite list.(Python)

Lets say I have list:
A = ['ldc','gnh','yjk','isd']
and
B = ['578','460','926','551']
My desired output would be:
gnh when my input is 460. (same position but from the other list) How to do this?
Make a dictionary where the keys would be the B list items and the values - A list items:
>>> d = dict(zip(B, A))
>>> d["460"]
'gnh'
Use the index built-in method to find the position in B.
Use that to grab the corresponding value from A.
Note that variable names do not go inside quotation marks.
A = ['ldc','gnh','yjk','isd']
B = ['578','460','926','551']
key = '460'
print A[B.index(key)]
for multiple entries:
for i, j in enumerate(B):
if j == key:
print A[i]
or a list thereof:
print [A[i] for i, j in enumerate(B) if j == key]
Output for the last one:
['gnh', '2nd']
you can use a generator and zip to scan and pair the lists
>>> key = '460'
>>> g = (a for a,b in zip(A,B) if b == key)
>>> next(g)
'gnh'
this also works for every occurrence of the key in the B list, in case it occurs more than once
e.g.
>>> A = ['ldc','gnh','yjk','isd']
>>> B = ['578','460','926','460']
>>> key = '460'
>>> g = (a for a,b in zip(A,B) if b == key)
>>> next(g)
'gnh'
>>> next(g)
'isd'
or use it as
>>> for el in g:
... print(el)
...
gnh
isd

Checking Python containers for an exact value instead of an equal value

Here's some example code:
>>> l = [ [0], [1], [2] ]
>>> z = [0]
>>> print z == l[0]
True
>>> print z is l[0]
False
>>> print z in l
True
Here's the behavior I'd like to be able to use:
>>> print z in l
False
>>> print l[0] in l
True
I know that I can do something like this, but it doesn't feel Pythonic.
>>> print any([z is i for i in l])
False
I feel like there could be an is in operator or something that I'm missing. What's the best way to handle this situation?

ValueError: max() arg is an empty sequence [python 3]

IS the list being nullified after calculating sum??
t = int(input())
while t > 0:
n,m=map(int,input().split())
a=map(int,input().split())
l,o=sum(a),max(a)
print(l)
if ((o * n)-l) == m:
print("YES")
else:
print((o * n)-l)
print("NO")
t = t-1
In Python 3 map() returns an iterator (unlike Python 2). The sum() function iterated over all the results already, and the iterator is now empty:
>>> sample = '1 2 3'
>>> map(int, sample.split())
<map object at 0x10523b2e8>
>>> a = map(int, sample.split())
>>> list(a)
[1, 2, 3]
>>> list(a)
[]
Use list() to copy the results to a list object, or better still, use a list comprehension instead of map():
a = [int(i) for i in input().split()]
Try like this:-
inputparam='100 2 300'
a = [int(i) for i in inputparam.split()]
maxNo=max(a)
sumno=sum(a)

Updating list in-place

I have a list of strings, some of them ends with new line symbol. I want to modify this list by removing \n from strings which ends with it. For this purpose I use the following code:
aList = ['qwerttyy\n', '123454\n', 'zxcv']
for s in aList:
if s.endswith('\n'):
s = s[: -1]
print(s)
The output is the following:
qwerttyy
123454
>>> aList
['qwerttyy\n', '123454\n', 'zxcv']
So the original list wasn't changed though list is mutable object. What is the reason of such behavior?
You can use slice assignment and a list comprehension:
>>> foo = aList = ['qwerttyy\n', '123454\n', 'zxcv']
>>> aList[:] = [s[:-1] if s.endswith('\n') else s for s in aList]
>>> foo #All references are affected.
['qwerttyy', '123454', 'zxcv']
>>> aList
['qwerttyy', '123454', 'zxcv']
Your code didn't work because it is equivalent to:
s = aList[0]
if s.endswith('\n'):
s = s[: -1]
s = aList[1]
if s.endswith('\n'):
s = s[: -1]
...
i.e You're updating the variable s, not the actual list item
because the for loop makes copies of strings.
You can use:
[s[:-1] if s.endswith('\n') else s for s in aList]
Maybe this is simpler, though it will remove also whitespaces.
[s.strip() for s in aList]
Using list comprehension and str.rstrip
>>> aList = ['qwerttyy\n', '123454\n', 'zxcv']
>>> [s.rstrip('\n') for s in aList]
['qwerttyy', '123454', 'zxcv']
Above will create new list. To modify the original list, use slicing (list[:] = ...):
>>> aList
['qwerttyy\n', '123454\n', 'zxcv']
>>> aList[:] = [s.rstrip('\n') for s in aList]
>>> aList
['qwerttyy', '123454', 'zxcv']
NOTE str.rstrip returns different result from [:-1] when tehre are multiple trailing newlines:
>>> 'qwerttyy\n\n'.rstrip('\n')
'qwerttyy'
>>> 'qwerttyy\n\n'[:-1]
'qwerttyy\n'
try this
>>> aList = ['qwerttyy\n', '123454\n', 'zxcv']
>>> aList = [x[:-1] if x.endswith('\n') else x for x in aList]
>>> aList
['qwerttyy', '123454', 'zxcv']

Categories

Resources