Matching the occurrence of the opposite number in a python list

I have a list of such

results = [100, 100, -100, 100, -100, -100]

I would like to find out the first occurrence of the opposite number. therefore, the first 100 will correspond to the first -100, the second 100 will correspond to the second -100.

I would like to have a position as an output, such as:

[0, 2], [1, 4], [3, 5]

ie: [0,2]represent results[0]and results[2], where the first occurrence of 100 corresponds to the first occurrence of -100

edit: you can assume that there will always be the same number of positive / negative and that the list will contain only 1 number

any help will be described

+4
source share
8 answers

IMO, ( ) ( , , , ):

x = [100, 300, -300, 100, -100, -100]

from collections import defaultdict, deque

unmatched_positives = defaultdict(deque)

solution=[]
for i, val  in enumerate(x):
    if val > 0:
        unmatched_positives[val].append(i)
    else:
        solution.append( (unmatched_positives[-val].popleft(), i) )

print('Unsorted solution:', solution)
# If you need the result to be sorted
print('Sorted solution:', sorted(solution))

:

Unsorted solution: [(1, 2), (0, 4), (3, 5)]
Sorted solution: [(0, 4), (1, 2), (3, 5)]
+2

, 2 (x -x), zip() :

indexes = [[],[]]
for i,x in enumerate(results):
    indexes[0].append(i) if x > 0 else indexes[1].append(i)
list(zip(*indexes))

:

>>> results = [100, 100, -100, 100, -100, -100]
>>> indexes = [[],[]]
>>> for i,x in enumerate(results): indexes[0].append(i) if x > 0 else indexes[1].append(i)
... 
>>> list(zip(*indexes))
[(0, 2), (1, 4), (3, 5)]

2 (, [i for i,x in enumerate(results) if x > 0] , for.

+3

:

results = [100, 100, -100, 100, -100, -100]

solution = []
for i, x in enumerate(results):
    if x > 0 and isinstance(x, int):
        y = results.index(-x)
        results[results.index(-x)] = 'found'
        solution.append([i,y])

print solution
+2

, :

solutions = []
for x in set(abs(x) for x in results):
    solutions += list(zip([i for i, x2 in enumerate(results) if x2 == x],
                          [i for i, x2 in enumerate(results) if x2 == x*-1]))
+2

, . , , :

from itertools import groupby

subresult = dict(map(lambda x:(x[0],iter(tuple(x[1]))),
                     groupby(sorted(filter(lambda x:x[1] < 0,enumerate(results)),
                             key=lambda x:x[::-1]),lambda x:x[1])
            ))

, :

subresult = filter(lambda x:x[1] < 0,enumerate(results)) # filter negative values
subresult = sorted(subresult,key=lambda x:x[::-1]) # sort them on value and then on index
subresult = groupby(subresult,lambda x:x[1]) # group them on the value
subresult = map(lambda x:(x[0],iter(tuple(x[1]))),subresult) # construct a sequence of tuples (value,list of indices)
subresult = dict(subresult) # make it a dictionary

:

{-100: <itertools._grouper object at 0x7fedfb523ef0>}

subresult. :

end_result = [[i,next(subresult[-v])[0]] for i,v in enumerate(results) if v > 0]

:

>>> subresult = dict(map(lambda x:(x[0],iter(tuple(x[1]))),groupby(sorted(filter(lambda x:x[1] < 0,enumerate(results)),key=lambda x:x[::-1]),lambda x:x[1])))
>>> [[i,next(subresult[-v])[0]] for i,v in enumerate(results) if v > 0]
[[0, 2], [1, 4], [3, 5]]

- , (, , ), .

+2

, ? , , zip , .

In [18]: neg_list = [idx for idx, el in enumerate(results) if el < 0]
In [19]: pos_list = [idx for idx, el in enumerate(results) if el > 0]

In [20]: neg_list
Out[20]: [2, 4, 5]

In [21]: pos_list
Out[21]: [0, 1, 3]

In [22]: list(zip(pos_list, neg_list))
Out[22]: [(0, 2), (1, 4), (3, 5)]

zip.


NumPy: ( ) numpy .

In [30]: res = np.array(results)
In [38]: pos_idx = np.where(res > 0)[0]
In [39]: pos_idx
Out[39]: array([0, 1, 3])

In [40]: neg_idx = np.where(res < 0)[0]
In [42]: neg_idx
Out[42]: array([2, 4, 5])

In [44]: list(zip(pos_idx, neg_idx))
Out[44]: [(0, 2), (1, 4), (3, 5)]

# If you want to avoid using zip, then 
# just use np.vstack and transpose the result
In [59]: np.vstack((pos_idx, neg_idx)).T
Out[59]: 
array([[0, 2],
       [1, 4],
       [3, 5]])

P.S.: generator comprehension , , .

In [24]: neg_gen = (idx for idx, el in enumerate(results) if el < 0)
In [25]: pos_gen = (idx for idx, el in enumerate(results) if el > 0)

In [27]: list(zip(pos_gen, neg_gen))
Out[27]: [(0, 2), (1, 4), (3, 5)]

# on 2nd run, there won't be any element in the generator.
In [28]: list(zip(pos_gen, neg_gen))
Out[28]: []
+2
pos = {}
for i,item in enumerate(results ):
    if item < 0: continue 
    if item not in pos:
       pos[item] = []
    pos[item].append(i)

[ [pos[-item].pop(0), i] for i,item in enumerate(results ) if item < 0]  

[[0, 2], [1, 4], [3, 5]]
+1

, results :

import numpy as np

results = np.array([100, 100, -100, 100, -100, -100])

output = list(zip(np.where(results > 0)[0], np.where(results < 0)[0]))

:

[(0, 2), (1, 4), (3, 5)]

~0.002 results * 1000.

+1

Source: https://habr.com/ru/post/1673720/


All Articles