поэлементная проверка вложенного списка - PullRequest
0 голосов
/ 25 апреля 2019

Поэлементно проверять вложенный список на наличие нескольких условий и возвращать 0 или 1, если условие не выполнено или выполнено.

Я должен проверить

как минимум 14

не могубыть равным = 19

, если элемент оканчивается на 4 или 9

Например, массив возраста

[[22, 13, 31, 13],
 [17, 14, 24, 22]]

будет иметь выходной массив как

[[0, 0, 0, 0], 
 [0, 1, 1, 0]]

Я попытался сгладить список и затем проверить каждое условие, но оно не работает.

flat_list = [item for sublist in age for item in sublist]
x=14
[not x for x in flat_list]

Ответы [ 4 ]

2 голосов
/ 25 апреля 2019

Существует более быстрое решение для numpy:

((arr >= 14) & (arr != 19) & ((arr%10 == 4) | (arr%10==9))).astype(int)

Код :

import numpy as np

arr = np.array([[22, 13, 31, 13],
                [17, 14, 24, 22]])

print(((arr >= 14) & (arr != 19) & ((arr%10 == 4) | (arr%10==9))).astype(int))

# [[0 0 0 0]
#  [0 1 1 0]]
1 голос
/ 25 апреля 2019

Вы можете сделать это с помощью списочных представлений, например так:

somelist = [[22, 13, 31, 13],
 [17, 14, 24, 22]]

result = [[1 if (x%10==4 or x%10==9) and (x>=14 and x!=19) else 0 for x in sublist] for sublist in somelist]

result
[[0, 0, 0, 0], [0, 1, 1, 0]]

Где x%10 будет получать последнюю цифру в каждом номере, что позволяет прямое сравнение. Сгруппировав два условия, вы можете более логично изложить, что вы хотите сделать, хотя для понимания списка это немного запутанно.

Лучшим способом (с потенциальной потерей скорости) может быть использование map:

def check_num(num):
    value_check = num >= 14 and num != 19
    last_num_check = num % 10 == 4 or num % 10 == 9
    return int(value_check and last_num_check)

somelist = [[22, 13, 31, 13],
 [17, 14, 24, 22]]

result = [[x for x in map(check_num, sublist)] for sublist in somelist]

result
[[0, 0, 0, 0], [0, 1, 1, 0]]

Время разницы между операциями:

Понимание списка

python -m timeit -s 'somelist = [[22, 13, 31, 13], [17, 14, 24, 22]]' '[[1 if (x%10==4 or x%10==9) and (x>=14 and x!=19) else 0 for x in sublist] for sublist in somelist]'
1000000 loops, best of 3: 1.35 usec per loop

Карта

python -m timeit -s 'from somefunc import check_num; somelist = [[22, 13, 31, 13], [17, 14, 24, 22]]' '[[x for x in map(check_num, sublist)] for sublist in somelist]'
100000 loops, best of 3: 3.37 usec per loop
0 голосов
/ 25 апреля 2019

У C.Nvis хороший ответ с пониманием списка. Вы также можете решить эту проблему, используя вложенные циклы

def is_valid(x):
    return (x == 14) or (x%10 == 4) or (x%10 == 9)

out = []

for sublist in matrix:
    out_sublist = []
    for i in sublist:
        if (is_valid(i)):
            out_sublist.append(1)
        else:
            out_sublist.append(0)
    out.append(out_sublist)

print(out)

Эти ответы по сути один и тот же алгоритм.

0 голосов
/ 25 апреля 2019

Только для вашего примера это может быть сделано с небольшим отображением.

Способ, которым вы можете проверить, что последняя цифра равна числу, заключается в применении к числу по модулю 10.

my_list = [[22, 13, 31, 13],[17, 14, 24, 22]]

result_list = []
for sublist in my_list:
    result_list.append(list(map(lambda x: 1 if x % 10 == 4 and x >= 14 and x != 19 else 0, sublist)))

print(result_list)

даст:

[[0, 0, 0, 0], [0, 1, 1, 0]]
...