How to pass the empty list when doing list comprehension - python

I have to create a list with all combination of three multiple lists:
a = ['1','2']
b = ['3','4']
c = ['5']
name = []
delimiter = '_'
name = [i + delimiter + j + delimiter + k for i in a for j in b if b for k in c]
print (name)
['1_3_5', '1_4_5', '2_3_5', '2_4_5']
My question is, on some occasions list c is empty.
c = []
print (name)
[]
Is there a way to prevent it returning as an empty list by altering the list comprehension, without removing "k in c"?

You can use an extendible method which does not rely on explicit nested for loops. For example, using itertools.product and filter:
from itertools import product
a = ['1','2']
b = ['3','4']
c = ['5']
res = ['_'.join(i) for i in product(*filter(None, (a, b, c)))]
# ['1_3_5', '1_4_5', '2_3_5', '2_4_5']
With empty c:
c = []
res = ['_'.join(i) for i in product(*filter(None, (a, b, c)))]
# ['1_3', '1_4', '2_3', '2_4']

Related

Adding each item from one list to each item from another list to third list

Image the following lists:
A = [1,2,3,4]
B = ['A','B','C','D']
C = [10,11,12,13]
D = [100,200,300,400]
I should get the following results:
Z = ['1A10100', '2B11200', '3C12300', '4D13400']
I can do this using a lot of empty arrays, do it first using a for loop for A and B than use this new list and append C for each i, etc.
The question is, can this be done in a smarter way. In my real case the lists are 6?
You can use a simple list comprehension:
Z = [''.join(str(x) for x in l) for l in zip(A,B,C,D)]
output: ['1A10100', '2B11200', '3C12300', '4D13400']
If you already have a container for your lists:
lists = [A,B,C,D]
[''.join(str(x) for x in l) for l in zip(*lists)]
Using a list comprehension we can try:
A = [1,2,3,4]
B = ['A','B','C','D']
C = [10,11,12,13]
D = [100,200,300,400]
nums = list(range(0, len(A)))
Z = [str(A[i]) + B[i] + str(C[i]) + str(D[i]) for i in nums]
print(Z) # ['1A10100', '2B11200', '3C12300', '4D13400']
If the length of each lists are fixed and same length you can simply loop by indices, concatenate them, and then push altogether one-by-one into the result array.
A = [1,2,3,4]
B = ['A','B','C','D']
C = [10,11,12,13]
D = [100,200,300,400]
# Prepare the empty array
result = []
# Concat and insert one-by-one
for i in range(len(A)):
result.append('{}{}{}{}'.format(A[i], B[i], C[i], D[i]))
print(result)
Output:
['1A10100', '2B11200', '3C12300', '4D13400']
There are also another way to concatenate and insert to the result array besides the code above:
You can assign a temporary variable to concatenate before inserting:
for i in range(len(A)):
tmp = str(A[i]) + B[i] + str(C[i]) + str(D[i])
result.append(tmp)
Or you can just put the variables in the inner curly brackets in this way
for i in range(len(A)):
result.append(f'{A[i]}{B[i]}{C[i]}{D[i]}')

how to separate list with the length of nested list python?

I have a nested list like this:
a = [[0.00069053395], [0.7278625], [0.8591849, 0.86290157, 0.8703022], [0.9041279, 0.9102304, 0.91197634], [0.93096334, 0.93327045], [0.9456768, 0.95339334], [0.98164046, 0.9836741]]
and another list like below:
b = ['/home/shape/13.jpg', '/home/shape/5.jpg', '/home/shape/6.jpg', '/home/shape/0.jpg', '/home/shape/2.jpg', '/home/shape/1.jpg', '/home/shape/7.jpg', '/home/shape/11.jpg', '/home/cuts/shape/10.jpg', '/home/shape/4.jpg', '/home/shape/14.jpg', '/home/shape/12.jpg', '/home/shape/16.jpg', '/home/shape/8.jpg']
I want to make the list b similar to nested list a, with its length of its elements.
Expected output:
c = [['/home/shape/13.jpg'],['/home/shape/5.jpg'],['/home/shape/6.jpg', '/home/shape/0.jpg', '/home/shape/2.jpg'],['/home/shape/1.jpg', '/home/shape/7.jpg', '/home/shape/11.jpg'],['/home/cuts/shape/10.jpg', '/home/shape/4.jpg'],['/home/shape/14.jpg', '/home/shape/12.jpg'],['/home/shape/16.jpg', '/home/shape/8.jpg']]
Any suggestions would be helpful!
You need:
c = []
count = 0
for i in a:
c.append(b[count:count+len(i)])
count = count+len(i)
print(c)
Output:
[['/home/shape/13.jpg'], ['/home/shape/5.jpg'], ['/home/shape/6.jpg',
'/home/shape/0.jpg', '/home/shape/2.jpg'], ['/home/shape/1.jpg',
'/home/shape/7.jpg', '/home/shape/11.jpg'], ['/home/cuts/shape/10.jpg',
'/home/shape/4.jpg'], ['/home/shape/14.jpg', '/home/shape/12.jpg'],
['/home/shape/16.jpg', '/home/shape/8.jpg']]
you could use the iter built-in function with list comprehension:
it = iter(b)
[[next(it) for _ in l] for l in a]
output:
[['/home/shape/13.jpg'],
['/home/shape/5.jpg'],
['/home/shape/6.jpg', '/home/shape/0.jpg', '/home/shape/2.jpg'],
['/home/shape/1.jpg', '/home/shape/7.jpg', '/home/shape/11.jpg'],
['/home/cuts/shape/10.jpg', '/home/shape/4.jpg'],
['/home/shape/14.jpg', '/home/shape/12.jpg'],
['/home/shape/16.jpg', '/home/shape/8.jpg']]

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

Python, toggle variables in a script

I've got a script running that I want to toggle between different variables.
Let's say I've got a list of urls and I want to concatenate one of the variables a, b or c. I don't care which but I'd expect the variables to repeat but the list would run through once.
v would end up looking like
url1+string1
url2+string2
url3+string3
url4+string1
url5+string2
etc
def function1():
list = [url1,url2,url3,url4,url5.......]
a = 'string1'
b = 'string2'
c = 'string3'
for i in list:
v = i+(a then b then c then a then b then c)
I was able to get this to work on my own but I'm new and learning, does anyone have a more elegant solution to this?
a = 'a'
b = 'b'
c = 'c'
list1 = ['string1','string2','string3','string4','string5','string6','string7','string8']
list2 = [a, b, c]
c = 0
for i in list1:
if c == len(list2):
c = 0
vv = i + list2[int(c)]
c = c + 1
print vv
it returns what I was looking for but it's messy:
string1a
string2b
string3c
string4a
string5b
string6c
string7a
string8b
You can utilise itertools.cycle to repeat one of the iterables, eg:
from itertools import cycle, izip
list1 = ['string1','string2','string3','string4','string5','string6','string7','string8']
list2 = ['a', 'b', 'c']
for fst, snd in izip(list1, cycle(list2)):
print fst + snd # or whatever
#string1a
#string2b
#string3c
#string4a
#string5b
#string6c
#string7a
#string8b
Note that while cycle will repeat its elements indefinitely, izip stops on the shortest iterable (list1).
list = [url1..1]
list2 = [a, b, c]
for i in list:
for a in list2:
v = i+a
EDIT
Okay, that makes more sense-
How about this...
set_it = iter(list2)
for i in list:
try:
a = set_it.next()
except:
set_it = iter(list2)
a = set_it.next()
v = i+a
Though I feel the same as you- there is probably a smoother way to accomplish that...

compare two lists with zeros en larger numbers

I have to compare two lists of elements with the same length. (as an example [0,562,256,0,0,856] and [265,0,265,0,874,958]. Both list have an amount of zeroes and an amount of numbers above 249. I want to compare these lists. If at an index both lists have a number different from 0 the number should be saved in a list. The result should be two lists with the same length with only numbers above 249 (in the example [256,856] and [265,958]). Thanks for your help!
Use zip() to pair up the elements of each list:
listA = [0,562,256,0,0,856]
listB = [265,0,265,0,874,958]
combined = zip(listA, listB)
resultA = [a for a, b in combined if a and b]
resultB = [b for a, b in combined if a and b]
gives:
>>> resultA
[256, 856]
>>> resultB
[265, 958]
You could also first use filter() to remove all pairs where one or the other element is 0:
combined = filter(lambda (a, b): (a and b), zip(listA, listB))
resultA = [a for a, b in combined]
resultB = [b for a, b in combined]
maybe we will find a better way,but
list1 = [0,562,256,0,0,856]
list2 = [265,0,265,0,874,958]
rest1 = []
rest2 = []
result1 = []
result2 = []
for i in range(len(list1)):
if list1[i] and list2[i]:
rest1.append(list1[i])
rest2.append(list2[i])
for i in range(len(rest1)):
if rest1[i] >249 and rest2[i]>249:
result1.append(rest1[i])
result2.append(rest2[i])
print(result1,result1)

Categories

Resources