简体   繁体   中英

Subtraction between two nested lists of strings in Python

I am trying to follow the used structure in this question for nested lists but I'm confused and don't know how to figure it out. Suppose that to subtract the two lists a = ['5', '35.1', 'FFD'] and b = ['8.5', '11.3', 'AMM'] , the following code is used for reaching to equation c = b - a:

diffs = []
for i, j in zip(a, b):
    try:
        diffs.append(str(float(j) - float(i)))
    except ValueError:
        diffs.append('-'.join([j, i]))
>>> print(diffs)
['3.5', '-23.8', 'AMM-FFD']

My question is, how do I get C = B - A by considering the following structure:

A = [['X1','X2'],['52.3','119.4'],['45.1','111']]

B = [['Y1','Y2'],['66.9','65'],['99','115.5']]

C = [['Y1-X1','Y2-X2'],['14.6','-54.4'],['53.9','4.5']]

and how do I the first and second elements of each internal list, something like:

 Array 1 = ['Y1-X1', '14.6', '53.9'] Array 2 = ['Y2-X2', '-54.4', '4.5'] 

I appreciate any kind of help.

Well, if it's guaranteed that the lists will always be 2 levels nested, you can simply add one more loop:

diffs_lists = []
for i, j in zip(a, b):
    diffs = []
    for k, l in zip(i, j):
        try:
            diffs.append(str(float(k) - float(l)))
        except ValueError:
            diffs.append('-'.join([k, l]))
    diffs_lists.append(diffs)

To separate the result in two as you asked, simply use zip:

zip(*diffs_lists)

You just need another level of looping:

res = []
for a, b in zip(A, B):
    diffs = []
    res.append(diffs)
    for i, j in zip(a, b):
        try:
            diffs.append(str(float(j) - float(i)))
        except ValueError:
            diffs.append('-'.join([j, i]))
print(res)
#[['Y1-X1', 'Y2-X2'], ['14.600000000000009', '-54.400000000000006'], ['53.9', '4.5']]
print(list(zip(*res)))
#[('Y1-X1', '14.600000000000009', '53.9'), ('Y2-X2', '-54.400000000000006', '4.5')]
diffs=[]
for sub_b, sub_a in zip(b, a):
    curr = []
    for atom_b, atom_a in zip(sub_b, sub_a):
        try:
            curr.append(float(atom_b) - float(atom_a))
        except ValueError:
            curr.append('-'.join([atom_b, atom_a]))
    diffs.append(curr)
ans1, ans2 = zip(*diffs)

The zip function can also be used to unzip iterables.

Suppose you have a list_diffs function, that is basically the code you provided:

list_diffs(a, b):
    diffs = []
    for i, j in zip(a, b):
        try:
            diffs.append(str(float(j) - float(i)))
        except ValueError:
            diffs.append('-'.join([j, i]))
    return diffs

Then, the C you want is just a list whose elements are diffs between elements of A and elements of B . So the following gives you C :

C = []
for i in range(len(A)):
    C.append(list_diffs(A[i], B[i]))

To get the lists of the first and of the second elements:

array1 = [c[0] for c in C]
array2 = [c[1] for c in C]

In case you need this to work with arbitrary amount of nesting you could use recursion:

def subtract(x, y):
    diffs = []
    for a, b in zip(x, y):
        try:
            if isinstance(a, list):
                diffs.append(subtract(a, b))
            else:
                diffs.append(str(float(b) - float(a)))
        except ValueError:
            diffs.append('-'.join([b, a]))

    return diffs

As others have pointed out zip can be used for unzipping:

res = subtract(A, B)
t1, t2 = zip(*res)
print(t1)
print(t2)

Output:

('Y1-X1', '14.6', '53.9')
('Y2-X2', '-54.4', '4.5')

i try it with a recursive method

A = [['X1','X2'],['52.3','119.4'],['45.1','111']]
B = [['Y1','Y2'],['66.9','65'],['99','115.5']]
C = [['Y1-X1','Y2-X2'],['14.6','-54.4'],['53.9','4.5']]

Array_a,Array_b = [[] for __ in range(2)]
def diff(B,A):
    _a = 0
    for b,a in zip(B,A):
        if isinstance(b,list):
            diff(b,a)
        else:
            try:
                Array_b.append(float(b)-float(a)) if _a else Array_a.append(float(b)-float(a))
                _a = True
            except (ValueError,TypeError) as e:
                Array_b.append("{0}-{1}".format(b,a)) if _a else Array_a.append("{0}-{1}".format(b,a))
                _a = True
    return (Array_a,Array_b)

print (diff(B,A))

>>>(['Y1-X1', 14.600000000000009, 53.9], ['Y2-X2', -54.400000000000006, 4.5])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM