python: самый элегантный способ пересечения списка с элементом
Входные данные:
intersperse(666, ["once", "upon", "a", 90, None, "time"])
Вывод:
["once", 666, "upon", 666, "a", 666, 90, 666, None, 666, "time"]
Какой из самых элегантных (читай: Pythonic) способ писать в нескольких intersperse
?
- Питонический способ обмена между списками?
- Как заменить каждый элемент в списке, кроме последнего
- Взятие элементов из списка
- Как вернуть ничего для разрезания списка Python
- Список внутри понимания списка
Я бы написал генератор сам, но вот так:
def joinit(iterable, delimiter): it = iter(iterable) yield next(it) for x in it: yield delimiter yield x
itertools
на помощь
– или –
Сколько функций itertools вы можете использовать в одной строке?
from itertools import chain, izip, repeat, islice def intersperse(delimiter, seq): return islice(chain.from_iterable(izip(repeat(delimiter), seq)), 1, None)
Применение:
>>> list(intersperse(666, ["once", "upon", "a", 90, None, "time"]) ["once", 666, "upon", 666, "a", 666, 90, 666, None, 666, "time"]
Другой вариант, который работает для последовательностей:
def intersperse(seq, value): res = [value] * (2 * len(seq) - 1) res[::2] = seq return res
Я бы пошел с простым генератором.
def intersperse(val, sequence): first = True for item in sequence: if not first: yield val yield item first = False
и тогда вы можете получить свой список следующим образом:
>>> list(intersperse(666, ["once", "upon", "a", 90, None, "time"])) ['once', 666, 'upon', 666, 'a', 666, 90, 666, None, 666, 'time']
вы также можете сделать:
def intersperse(val, sequence): for i, item in enumerate(sequence): if i != 0: yield val yield item
Я не уверен, что больше pythonic
def intersperse(word,your_list): x = [j for i in your_list for j in [i,word]] >>> intersperse(666, ["once", "upon", "a", 90, None, "time"]) ['once', 666, 'upon', 666, 'a', 666, 90, 666, None, 666, 'time', 666]
[Изменить] Исправленный код ниже:
def intersperse(word,your_list): x = [j for i in your_list for j in [i,word]] x.pop() return x >>> intersperse(666, ["once", "upon", "a", 90, None, "time"]) ['once', 666, 'upon', 666, 'a', 666, 90, 666, None, 666, 'time']
Как насчет:
from itertools import chain,izip_longest def intersperse(x,y): return list(chain(*izip_longest(x,[],fillvalue=y)))
Dunno, если это pythonic, но это довольно просто:
def intersperse(elem, list): result = [] for e in list: result.extend([e, elem]) return result[:-1]
Это работает:
>>> def intersperse(e, l): ... return reduce(lambda x,y: x+y, zip(l, [e]*len(l))) >>> intersperse(666, ["once", "upon", "a", 90, None, "time"]) ('once', 666, 'upon', 666, 'a', 666, 90, 666, None, 666, 'time', 666)
Если вы не хотите отставать 666
, return reduce(...)[:-1]
.
Я только что придумал это сейчас, googled, чтобы увидеть, есть ли что-то лучше … и ИМХО не было 🙂
def intersperse(e, l): return list(itertools.chain(*[(i, e) for i in l]))[0:-1]
def intersperse(items, delim): i = iter(items) return reduce(lambda x, y: x + [delim, y], i, [i.next()])
Должен работать для списков или генераторов.
- Python 2: различное значение ключевого слова «in» для наборов и списков
- Как сделать каждый элемент списком из zip () со списком?
- Запись и чтение списков в текстовые файлы в Python: есть ли более эффективный способ?
- создание списка кортежей с использованием цикла
- Подсчет элементов в списке – путь python
- Алфавит и рекурсия
- Попытка понимания списка Python с двумя переменными разных диапазонов
- Как проверить, что каждый список в списке списка имеет одинаковую длину
- Python изменит тип всего списка?