How to reverse a sublist in python - python

Given the following list:
a = ['aux iyr','bac oxr','lmn xpn']
c = []
for i in a:
x = i.split(" ")
b= x[1][::-1] --- Got stuck after this line
Can anyone help me how to join it to the actual list and bring the expected output
output = ['aux ryi','bac rxo','lmn npx']

I believe you need two lines of codes, first splitting the values:
b = [x.split() for x in a]
Which returns:
[['aux', 'iyr'], ['bac', 'oxr'], ['lmn', 'xpn']]
And then reverting the order:
output = [x[0] +' '+ x[1][::-1] for x in b]
Which returns:
['aux ryi', 'bac rxo', 'lmn npx']

You can use the following simple comprehension:
[" ".join((x, y[::-1])) for x, y in map(str.split, a)]
# ['aux ryi', 'bac rxo', 'lmn npx']

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]}')

Adding special character to a column names

I have a list of column names that are in string format like below:
lst = ["plug", "plug+wallet", "wallet-phone"]
I want to add df[] along with " ' ".
I am using regex to substitute it. But the regex which I am using works fine when the list is like this:-
lst = [" 'plug'", "'plug'+'wallet'", "'wallet'-'phone'"]
x=[]
for l in lst: x.append(re.sub(r"('[^+\-*\/'\d]+')", r'df[\1]',l))
print(x)
the result is as excepted
x: [" df['plug']", "df['plug']+df['wallet']", "df['wallet']-df['phone']"]
But when list is like this:
lst = ["plug", "plug+wallet", "wallet-phone"]
x=[]
y=[]
for l in lst: x.append(re.sub(r"('[^+\-*\/'\d]+')", r'\1',l))
for f in x: y.append(re.sub(r"('[^+\-*\/'\d]+')", r'df[\1]',f))
print(x)
print(y)
This gives:
['plug', 'plug+wallet', 'wallet-phone']
['plug', 'plug+wallet', 'wallet-phone']
Where am I going wrong? Am I missing anything in the first regex pattern or not passing the r'\1' properly?
Excepted Output:
x: [" 'plug'", "'plug'+'wallet'", "'wallet'-'phone'"]
y: [" df['plug']", "df['plug']+df['wallet']", "df['wallet']-df['phone']"]
This works:
import re
lst = ["plug", "plug+wallet", "wallet-phone"]
x = [re.sub(r"([^+\-*\/'\d]+)", r"'\1'", l) for l in lst]
y = [re.sub(r"('[^+\-*\/'\d]+')", r"df[\1]", l) for l in x]
print(x)
print(y)
Your first regular expression was wrongly matching on the '' and was then in the replace subject not enclosing it in ''.
Tested under Python 3.8.0.

Remove element from sublist according to another list

I have a list filled with sublist:
a = [['12345/0111','57894/0311','45698/2333'],['12345/0600','87456/1234']]
Then I have another list:
b = ['0111','0600','0311']
I would like to delete all elements from list a which doesn't contain elements from list b.
I thought that it should be like this for the firts element in b (in this case 45698/2333 and 87456/1234):
for x in a:
for y in x:
if b[0] not in y:
x.remove(y)
But it doesn't work even for the first element and I really don't know how to do it for all the elements in b.
EDIT: I am sorry I didn't specified that in the output I need to have the same nested list structure.
Give this a try:
# create a new list to store values
c = []
for x in a:
for y in x:
if str.split(y, '/')[1] in b:
c.append(y)
My Results:
a
[['12345/0111', '57894/0311', '45698/2333'], ['12345/0600', '87456/1234']]
b
['0111', '0600', '0311']
c = []
for x in a:
for y in x:
if str.split(y, '/')[1] in b:
c.append(y)
c
['12345/0111', '57894/0311', '12345/0600']
EDITED AFTER OP CLARIFICATION:
for x in a:
for y in x:
if str.split(y, '/')[1] in b:
x.remove(y)
EDITED RESULTS:
for x in a:
for y in x:
if str.split(y, '/')[1] in b:
x.remove(y)
a
[['57894/0311', '45698/2333'], ['87456/1234']]
You're saying to remove anything that's in b, which doesn't appear to be what you mean. In any case if you remove the 'not' from either of the following two samples they will give you the ones that are in b.
a = [['12345/0111','57894/0311','45698/2333'],['12345/0600','87456/1234']]
b = ['0111','0600','0311']
Not Nested
output = []
for l in a:
for e in l:
if not any([x in e for x in b]):
output.append(e)
Nested
output = []
for l in a:
output.append([x for x in l if not any(z in x for z in b)])

ignore empty string in a list or when there is a $none

I would like to totally ignored these lists within a list when there is an empty string or when there is a "$none" string (by the way, why does this "$none" appears and what does it mean?). In my program, I returned the list an empty string when using this:
Code:
aaa = ["mom", "is", "king"]
example = ["buying", "mom", "is", "spending"]
Below code:
for x in aaa:
if xx in example:
if x in xx:
return ""
else:
return xx
I only know how to return an empty string but do not know other way of ignore this part of "if" when triggered
If the above cannot be done, then the below will be my main question.
My code:
a = [['checking-$none', ''],
['', 'checking-some'],
['checking-people', 'checking-might'],
['-checking-too', 'checking-be']]
for x in a:
f = filter(None, x)
for ff in f:
print(ff)
Current output:
checking-$none
checking-some
checking-people
checking-might
-checking-too
checking-be
Expected output:
checking-people
checking-might
-checking-too
checking-be
Is there a way to do so?
You can use list comprehension like this:
[item for lst in a if all(item and '$none' not in item for item in lst) for item in lst]
With your sample input a, this returns:
['checking-people', 'checking-might', '-checking-too', 'checking-be']
Alternatively, if you only want to print, the following nested for loop will do:
for lst in a:
for item in lst:
if not item or '$none' in item:
break
else:
print(*lst, sep='\n')
This outputs:
checking-people
checking-might
-checking-too
checking-be
Min change to you code would be filter out string that contains $none
a = [['checking-$none', ''],
['', 'checking-some'],
['checking-people', 'checking-might'],
['-checking-too', 'checking-be']]
f = filter(lambda y: '' not in y and "checking-$none" not in y, a)
for x in sum(f, []):
print(x)

restoring list from unified_diff output

I need to generate the diff between two arrays of strings:
a=['1','2']
b=['1','2','3']
To achieve this I'm using the difflib library in Python (2.6):
c=difflib.unified_diff(a,b)
and I save the content of
d=list(c)
which is something like:
['--- \n', '+++ \n', '## -1,2 +1,3 ##\n', ' 1', ' 2', '+3']
How can I build the second array from the first using the output of the unified_diff function?
The behavior that I'm looking for is something like:
>>> merge(a,d)
>>> ['1','2','3']
P.S. the array can have duplicate entries and the order in which each entry appears is important for my application. Moreover, from one iteration to another there could be changes both in the middle/begin of the array, as well as new entries added at the end.
Not sure that my sample is a good style, but you can use something like this:
from collections import Counter
a=['1','2']
b=['1','2','3']
a.extend(b)
[k for k,v in Counter(a).items() if v == 1]
OR if your lists could have only unique items:
list(set(a) ^ set(b))
OR:
missed_in_a = [x for x in a if x not in b]
missed_in_b = [x for x in b if x not in a]
OR:
a=['1','2']
b=['1','2','3']
c = [x for x in a]
c.extend(b)
diff = [x for x in c if a.count(x)+b.count(x) == 1]
The last one(hope i understand you correctly(sorry if not so) now):
a = ['1','2','3','4']
b = ['2','2','3','6','5']
from difflib import unified_diff
def merge(a,b):
output = []
for line in list(unified_diff(a,b))[3:]:
if '+' in line:
output.append(line.strip('+'))
elif not '-' in line:
output.append(line.strip())
return output
print merge(a,b)

Categories

Resources