Как мне сопоставить несколько функций в списке? - PullRequest
0 голосов
/ 26 февраля 2020

Дело дошло до:

Как мне сопоставить несколько функций в списке?

items = ['this', 'that', 100]
item_types = (type(i) for i in items)
items_gen = map(next(item_types), items)

Это не работает, как и многие другие вещи, которые я пробовал. Чего мне не хватает?

Я получаю либо первый тип, сопоставленный по всему списку, либо тип, примененный к первому элементу и сам по себе разрезанный на фрагменты символов ...

Если это дурак - извините, я не могу найти этот вопрос каким-либо разумным способом, который задают здесь из-за миллиона способов.

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

Ожидаемый результат: я хочу вызвать next для этого объекта item_gen и получить: 'this', 'that', 100 Not: 'this', 'то', '100'

Ответы [ 4 ]

1 голос
/ 26 февраля 2020

[см. РЕДАКТИРОВАТЬ ниже] Я думаю, вам нужен еще один генератор в цепочке, если это то, что вы ищете, система преобразования типов (или проверки?)?

def mapper(typedefs, target):
    igen = (i for i in typedefs)
    item_types = (type(i) for i in igen)
    return map(next(item_types), target)

, тогда если вы скажете:

list(mapper(['a','b','c'],[1,2,3]))

Вы получите:

['1','2','3']

Однако при обратном преобразовании будут возникать исключения ValueError.

[EDIT]: это неверно выше. Это выглядит хорошо:

def foo(types, target):
    if len(types) == len(target):
        gen1 = (type(i) for i in types)
        gen2 = ([i] for i in target)   #key is make this a list
        gen3 = (next(map(next(gen1),next(gen2))) for _ in types)
        yield from gen3

Теперь мы получаем преобразование типов по элементам (попытки):

bar = foo(['a',True,3.14,1],[1,1,1,1]))
list(bar)
['1',True,1.0,1]
1 голос
/ 26 февраля 2020

Вы можете просто повторить 2 и применить каждую функцию к каждому элементу. Пример:

>>> def f1(x): return x+1
... 
>>> def f2(x): return x+2
... 
>>> def f3(x): return x+3
... 
>>> functions = [f1,f2,f3]
>>> elements = [1,1,1]
>>> [f(el) for f,el in zip(functions,elements)]
[2, 3, 4]

Который в вашем случае становится:

>>> [f(el) for f,el in zip(item_types,items)]
['this', 'that', 100]
0 голосов
/ 26 февраля 2020

Чтобы использовать map здесь, вам необходимо отобразить приложение функции . затем вы можете использовать форму с несколькими аргументами map, что-то вроде:

>>> funcs = [lambda x: x+1, lambda x: x*2, lambda x: x**3]
>>> data = [1, 2, 3]
>>> def apply(f, x): return f(x)
...
>>> list(map(apply, funcs, data))
[2, 4, 27]

Примечание. Передача next(item_types) не имеет смысла, что дает вам следующий элемент в item_types, который в этот случай относится к первому типу, если вы хотите понять, что вы видели раньше.

Или, например,

>>> items = ['this', 'that', 100]
>>> list(map(apply, map(type, items), items))
['this', 'that', 100]
0 голосов
/ 26 февраля 2020

То, что вы, похоже, хотите сделать, - это создать генератор из списка (я не уверен, для чего существует целая вещь type).

Чтобы сделать это, вы можете просто позвонить iter:

item_gen = iter(items)
res = []
res.append(next(item_gen))
res.append(next(item_gen))
res.append(next(item_gen))
print(res)

напечатает (и типы будут оригинальными):

['this', 'that', 100]

Если у вас есть только один набор типов в списке types и вы хотите, чтобы они применялись, вы можете сделать следующее:

types = [str, str, int]
item_gen = (tp(i) for tp, i in zip(types, items))
...