10
votes

Equivalent python de chaque_slice de Ruby (compte)

Qu'est-ce que l'équivalent Pythons du chaque_slice de Ruby (compte) ?
Je veux prendre 2 éléments de la liste pour chaque itération.
Comme pour [1,2,3,4,5,6] je veux gérer 1,2 dans la première itération, puis 3,4 Ensuite, 5,6 .
Bien sûr, il y a un chemin rond-point en utilisant des valeurs d'index. Mais y a-t-il une fonction directe ou quelque chose à faire directement?


1 commentaires

La réponse de Mark satisfait complètement les spécifications que vous avez fournies dans votre question. Cependant, il est important de noter que le comportement qu'il a spécifié est écarté de Ruby's Wash_slice: Si la dernière tranche est plus courte que le reste, il sera rembourré avec FillValue, tandis que dans Ruby's Chaque_slice, il s'agit simplement d'une matrice raccourcie. Si vous voulez ce comportement de liste raccourci / iTAKEF, la réponse de Mark ne fonctionnera pas.


6 Réponses :


10
votes

Il y a un Recette pour cela dans ITERTOOLS Documentation appelée GRAPER:

>>> l = [1,2,3,4,5,6]
>>> for a,b in grouper(2, l):
>>>     print a, b

1 2
3 4
5 6


1 commentaires

Remarque: Utilisez ZIP_LONGEST au lieu de Izip_longest pour Python 3.



2
votes

Même chose que Mark's mais renommé à 'chacun_slice' et fonctionne pour Python 2 et 3: xxx


0 commentaires

4
votes

DUPLICATES Comportement de Ruby's Chaque_slice pour une petite tranche de fuite: xxx

Les réponses ci-dessus couvront la dernière liste (c'est-à-dire [5, aucune]), ce qui peut ne pas être souhaité certains cas.


0 commentaires

0
votes

Une amélioration des deux premiers: Si le tranchant iérien n'est pas tout à fait divisible par N, le dernier sera rempli à la longueur n sans. Si cela vous amène à saisir des erreurs, vous pouvez faire une petite modification:

def each_slice(iterable, n, fillvalue=None):
    args = [iter(iterable)] * n
    raw = izip_longest(fillvalue=fillvalue, *args)
    return [filter(None, x) for x in raw]


0 commentaires

3
votes

Je sais que cela a été répondu par de multiples experts sur la langue, mais j'ai une approche différente à l'aide d'une fonction de générateur qui est plus facile à lire et à motiver en fonction de vos besoins:

def each_slice(list: List[str], size: int):
    batch = 0
    while batch * size < len(list):
        yield list[batch * size:(batch + 1) * size]
        batch += 1   

slices = each_slice(["a", "b", "c", "d", "e", "f", "g"], 2)
print([s for s in slices])

$ [['a', 'b'], ['c', 'd'], ['e', 'f'], ['g']]


1 commentaires

J'ai remarqué la réponse de @ BWV549, mais la mienne utilise la syntaxe de la tranche de réseau existante au lieu de créer un tableau et d'y ajouter.



0
votes
s_size = 4
l = list(range(100))

while len(l) > 0:
    slice = [l.pop() for _e,i in enumerate(l) if i <= s_size ]
    print(slice)

0 commentaires