Понимание списка Добавить коэффициенты дважды по одному разу - PullRequest
7 голосов
/ 29 марта 2019

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

Проблема связана со следующим вопросом: у нас есть массив [1,2, 3,8,9] и хотим создать выражение, которое бы возвращало каждое нечетное число дважды, в то время как четные числа возвращались только один раз.

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

Вывод соответствующего алгоритма должен быть: [1,1,2,3,3,8,9,9]

Используя цикл, я мог бы делать то, что я хочу, вот так:

OtherNumList = [1, 2, 3, 8, 9]
OtherNumList2 = []
for i in OtherNumList:
    if i%2==1:
        OtherNumList2.append(i)
        OtherNumList2.append(i)
    else:
        OtherNumList2.append(i)
print(OtherNumList2)

Я хочу сделать это, используя только выражение, или иначе «однострочно», используя понимание списка.

Я изо всех сил пытаюсь понять, как настроить понимание так, чтобы оно добавлялось дважды, если X, и добавлялось один раз, если Y.

Буду признателен за вашу помощь в понимании даже только концепции построения понимания;Я не ожидаю решения, получаемого с помощью ложки, и предпочел бы, чтобы вы помогли мне пройти через процесс мышления, чтобы я мог лучше заложить свои собственные основы для лучшего понимания списка в будущем!:)

Ответы [ 5 ]

10 голосов
/ 29 марта 2019

Вы можете сделать это в едином понимании списка без внешних инструментов. Вам просто нужно создать и пройти внутреннюю последовательность значений на основе значения, извлеченного из внешней последовательности:

OtherNumList = [1, 2, 3, 8, 9]
OtherNumList2 = [rep for i in OtherNumList for rep in (i,)*(i%2+1)]
print(OtherNumList2)

Трюк здесь второй for. Он повторяет tuple из одной или двух копий i, в зависимости от того, является ли i четным (одна копия) или нечетным (две копии). Для удобства нам даже не нужна настоящая логическая проверка; (i%2+1) всегда 1 для четного и 2 для нечетного, поэтому мы можем использовать его для умножения напрямую. Результирующее значение затем получается правильное число раз напрямую, без необходимости дополнительного выравнивания.

3 голосов
/ 29 марта 2019

Одним из способов может быть создание вложенного списка и последующее его выравнивание, используя, например, itertools.chain. Сложная задача - сразу создать плоский список, так как вам придется добавлять более одного элемента одновременно, когда условие не выполняется, поэтому вам нужно немного поработать, чтобы сгладить результирующий список:

from itertools import chain
list(chain.from_iterable([i] if i%2 == 0 else [i]*2 for i in l))

Выход

[1, 1, 2, 3, 3, 8, 9, 9]

Хотя мне кажется, что оптимальный способ сделать это - использовать функцию генератора или очень похожую функцию, которой вы поделились, но, возможно, предпочтительнее для больших списков:

def my_fun(l):
    for i in l:
        if i%2 == 0:
            yield i
        else:
            yield i
            yield i

list(my_fun(l))
# [1, 1, 2, 3, 3, 8, 9, 9]
1 голос
/ 29 марта 2019

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

x = [1, 2, 3, 8, 9]
[[value]*(value%2+1) for value in x]
1 голос
/ 29 марта 2019

Одна идея состоит в том, чтобы сначала дать список списков, как подсказал вам подсказка.

nested_list = [[i] if i % 2 == 0 else [i] * 2 for i in NumList] 

Это даст вам следующее:

[[1, 1,], [2], [3, 3], [8], [9, 9]]

Теперь вам просто нужно сгладить этот массив в одной строке. Чтобы сделать это, я обращаюсь к верхнему ответу здесь: Как сделать плоский список из списка списков?

1 голос
/ 29 марта 2019
import numpy as np
num_list = [1, 2, 3, 8, 9]
new_list = []

for x in num_list:
    new_list.extend(np.repeat(x, 2, axis=0)) if x%2 == 1 else new_list.append(x)
...