modify list element with list comprehension in python - python

folks,
I want to modify list element with list comprehension. For example, if the element is negative, add 4 to it.
Thus the list
a = [1, -2 , 2]
will be converted to
a = [1, 2, 2]
The following code works, but i am wondering if there is a better way to do it?
Thanks.
for i in range(len(a)):
if a[i]<0:
a[i] += 4

a = [b + 4 if b < 0 else b for b in a]

If you want to change the list in-place, this is almost the best way. List comprehension will create a new list. You could also use enumerate, and assignment must be done to a[i]:
for i, x in enumerate(a):
if x < 0:
a[i] = x + 4

This version is older, it would work on Python 2.4
>>> [x < 0 and x + 4 or x for x in [1, -2, 2]]
0: [1, 2, 2]
For newer versions of Python use conditional expressions as in Adam Wagner or BenH answers

Try this:
b = [x + 4 if x < 0 else x for x in a]
Or if you like map more than a list comprehension:
b = map(lambda x: x + 4 if x < 0 else x, a)

Why mutate, when you can just return a new list that looks like you want it to?
[4 + x if x < 0 else x for x in [1, -2, 2]]

Related

How to check whether an element in list is in another list and at which index? [duplicate]

This question already has answers here:
Finding the index of an item in a list
(43 answers)
Closed 1 year ago.
Let's say I have two lists
a = [1,2,3,4]
b = [5,9,1,2]
and I want to get the indices of every element in list b when an element of list a is in there. In this example, the result should be a list c containing all indices in b
c = [2,3]
1 in list a is on index 2 in b
2 in list a is on index 3 in b
Thanks in advance!!
[index for (index, item) in enumerate(b) if item in a]
output
[2, 3]
Use this:
c = [b.index(x) for x in a if x in a and x in b]
c
Output:
[2, 3]
I would solve that this way:
a = [1, 2, 3, 4]
b = [5, 9, 1, 2]
b_d = {b[i]: i for i in range(len(b))}
result = [b_d[v] for v in a if v in b_d]
print(result)
Using a set will make the inclusion check faster:
set_a = set(a)
c = [i for i, x in enumerate(b) if x in set_a]
You could simply iterate over the first list, then check if the item is inside the second list, if yes then append the index to your new list c:
a = [1,2,3,4]
b = [5,9,1,2]
c = []
for item in list_a:
if item in list_b:
c.append(list_b.index(item))
print(c)
Or use a list comprehension:
[list_b.index(item) for item in list_a if item in list_b]

Comparing two lists and making new list

So lets say I have two lists a=[1,2,3,4,5,6] and b=[2,34,5,67,5,6] I want to create a third list which will have 1 where elements are different in a and b and 0 when they are same, so above would be like c=[1,1,1,1,0,0]
You can zip the lists and compare them in a list comprehension. This takes advantage of the fact that booleans are equivalent to 1 and 0 in python:
a=[1,2,3,4,5,6]
b=[2,34,5,67,5,6]
[int(m!=n) for m, n, in zip(a, b)]
# [1, 1, 1, 1, 0, 0]
Try a list comprehension over elements of each pair of items in the list with zip:
[ 0 if i == j else 1 for i,j in zip(a,b) ]
Iterating with a for loop is an option, though list comprehension may be more efficient.
a=[1,2,3,4,5,6]
b=[2,34,5,67,5,6]
c=[]
for i in range(len(a)):
if a[i] == b[i]:
c.append(0)
else:
c.append(1)
print(c)
prints
[1, 1, 1, 1, 0, 0]
If you will have multiple vector operations and they should be fast. Checkout numpy.
import numpy as np
a=[1,2,3,4,5,6]
b=[2,34,5,67,5,6]
a = np.array(a)
b = np.array(b)
c = (a != b).astype(int)
# array([1, 1, 1, 1, 0, 0])
idk if this is exactly what youre loocking for but this should work:
edidt: just found out that Joe Thor commented almost the exact same a few minutes earlier than me lmao
a = [1, 2, 3, 4, 5, 6]
b = [2, 34, 5, 67, 5, 6]
results = []
for f in range(0, len(a)):
if a[f] == b[f]:
results.append(0)
else:
results.append(1)
print(results)
This can be done fairly simply using a for loop. It does assume that both lists, a and b, are the same length. An example code would like something like this:
a = [1,2,3,4,5,6]
b = [2,34,5,67,5,6]
c = []
if len(a) == len(b):
for i in range(0,len(a)):
if(a[i] != b[i]):
c.append(1)
else:
c.append(0)
This can also be done using list comprehension:
a = [1,2,3,4,5,6]
b = [2,34,5,67,5,6]
c = []
if len(a) == len(b):
c = [int(i != j) for i,j in zip(a,b)]
The list comprehension code is from this thread: Comparing values in two lists in Python
a = [1, 2, 3, 4, 5, 6]
b = [2, 34, 5, 67, 5,6]
c = []
index = 0
x = 1
y = 0
for i in range(len(a)): # iterating loop from index 0 till the last
if a[index]!= b[index]: # comapring each index
c.append(x) # if not equal append c with '1'
index += 1 # increment index to move to next index in both lists
else:
c.append(y)
index += 1
print(c)
This should work for two lists of any type.
tstlist = ["w","s","u"]
lstseasons = ["s","u","a","w"]
lstbool_Seasons = [1 if ele in tstlist else 0 for ele in lstseasons]
Output: lstbool_Seasons = [1,1,0,1]
This is the first time I have posted anything, still figuring out how things work here, so please forgive faux pas...

nested loops and conditional checks in list comprehensions (python)

I'm currenty learning list comprehension in Python and I want to write a function that takes two lists, a and b, and returns all elements of a that are divisible by all elements of b.
The equivalent of this (not using list comprehension) would be:
a = [10, 5]
b = [5, 2]
c = []
d = True
for i in a:
for j in b:
if i % j != 0:
d = False
if d:
c.append(i)
return c
How can I do this with list comprehension?
I currently have [x for x in a for y in b if x % y == 0] but that only requires x to match one of the items in b, not all of them.
Try this one:
a = [10, 5]
b = [5, 2]
res = [x for x in a if all(x % y == 0 for y in b)]
for completion on #superb rain 's comment. Here is also an example for any(...):
res = [x for x in a if not any(x % y != 0 for y in b)]

Update elements of array according to other array in one line?

I have two arrays called y and R(same dimensions). R consists of 1 and 0's. I am trying to change y's elements to 0 if according element of R is 0, otherwise keep it same.
I attempted this one line:
y=[0 for a in y if for b in r if b==0]
but it says invalid syntax. How should I change it?
You could enumerate one list, accessing the other list by index:
y = [2,3,4,5,6,7]
R = [0,0,1,1,0,1]
res = [ 0 if R[i] == 0 else a for i, a in enumerate(y) ]
#=> [0, 0, 4, 5, 0, 7]
Or
[ 0 if r == 0 else y[i] for i, r in enumerate(R) ]
#=> [0, 0, 4, 5, 0, 7]
Alternative using NumPy:
import numpy as np
y = np.array([2,3,4,5,6,7])
R = np.array([0,0,1,1,0,1])
print(y * R)
#=> [0 0 4 5 0 7]
Rewrite your list comprehension this way:
y = [0 if j == 0 else i for i, j in zip(y, R)]
Your invalid sintax error comes from the for immediately after the if, it does not mean anything for the interpreter.

Compare 2 lists and print the element of the 2nd list if it is present in first list, but not by using 2 for loops

I have to compare 2 lists, if element of list a is present in list b, then the element of list b is to print.
a = [1, 3, 2, 1, 3]
b = [2, 2, 1, 1, 1, 4, 2, 3]
ans = [1, 1, 1, 3, 2, 2, 2, 1, 1, 1, 3]
I may get the answer by using 2 for loops like:
for a_ in a:
for b_ in b:
if a_ == b_:
print b_
op: 1 1 1 3 2 2 2 1 1 1 3
But I don't want to use 2 for loops. How can I do that with a single loop?
Use collections.Counter to count for you:
from collections import Counter
c = Counter(b)
ans = []
for x in a:
ans += [x]*c.get(x,0)
This is one potential way (a bit messy), just posting it since it turns out Fabricator didn't end up with the correct result.
[item for sublist in ([i] * b.count(i) for i in a) for item in sublist]
Basically, the ([i] * b.count(i) for i in a) part builds the list, but it ends up as a list of lists, so then I did the [item for sublist in list for item in sublist] thing to flatten the list.
It's probably a bit similar to the answer by zondo but this keeps it as a list of numbers instead of a string.
print(" ".join(str(x) for x in a for _ in range(b.count(x))))
This, should be work:
for a_ in a:
if b.count(a_) :
ans+=((str(a_)+' ')*b.count(a_)).strip().split(' ')
list.count(x) count the number of occourrences of x in list.
you can print n times a string simply: *'mystring'times
Hope I helped you!

Categories