C'est arrivé à ceci:

Comment mapper plusieurs fonctions sur une liste?

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

Cela ne fonctionne pas, pas plus que beaucoup d'autres choses que j'ai essayées. Qu'est-ce que je rate?

J'obtiens soit le premier type mappé sur toute la liste, soit le type appliqué au premier élément et lui-même découpé en extraits de caractères ...

S'il s'agit d'un dupe - désolé, je ne trouve pas cette question de manière raisonnable posée ici en raison d'un million de façons.

Je vais changer les éléments pour input () donc ce n'est qu'un exemple grossier, mais je veux appliquer des types aux valeurs d'entrée.

Sortie attendue: je veux appeler ensuite sur cet objet item_gen et obtenir: 'ceci', 'cela', 100 Pas: 'ceci', 'cela', '100'

0
Vaidøtas Ivøška 26 févr. 2020 à 01:35

4 réponses

Meilleure réponse

[voir MODIFIER ci-dessous] Je pense que vous avez besoin d'un générateur de plus dans la chaîne, si c'est ce que vous recherchez, un système de conversion (ou de vérification?) de type?

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

Alors si vous dites:

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

Vous obtiendriez:

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

Cependant, cela générera des exceptions ValueError dans la conversion inverse.

[EDIT]: c'est incorrect ci-dessus. Cela semble bon:

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

Maintenant, nous obtenons une conversion de type article par article (tentatives):

bar = foo(['a',True,3.14,1],[1,1,1,1]))
list(bar)
['1',True,1.0,1]
1
neutrino_logic 26 févr. 2020 à 01:11

Ce que vous semblez vouloir faire, c'est créer un générateur à partir d'une liste (je ne sais pas à quoi sert tout type).

Pour ce faire, vous pouvez simplement appeler iter:

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

S'imprimera (et les types seront les originaux):

['ceci', 'cela', 100]

En supposant que vous avez un seul ensemble de types dans une liste types et que vous souhaitez qu'ils soient appliqués, vous pouvez faire la chose suivante:

types = [str, str, int]
item_gen = (tp(i) for tp, i in zip(types, items))
0
sophros 25 févr. 2020 à 23:47

Vous pouvez simplement compresser 2 itérables et appliquer chaque fonction à chaque élément. Exemple:

>>> 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]

Ce qui dans votre cas devient:

>>> [f(el) for f,el in zip(item_types,items)]
['this', 'that', 100]
1
abc 25 févr. 2020 à 22:52

Pour utiliser map ici, vous devez mapper l'application de fonction . alors, vous pouvez utiliser la forme multi-arguments de map, quelque chose comme:

>>> 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]

Notez que passer next(item_types) n'a aucun sens, cela vous donne l'élément suivant dans item_types, qui dans ce cas, est le premier type, si vous voulez comprendre ce que vous voyiez auparavant.

Ou, avec votre exemple:

>>> items = ['this', 'that', 100]
>>> list(map(apply, map(type, items), items))
['this', 'that', 100]
0
juanpa.arrivillaga 25 févr. 2020 à 22:56