Начин за повторение на два елемента наведнъж в списък?

Чудя се дали има по-добър начин за повторение на два елемента наведнъж в списък. Работя много с Maya и една от неговите команди (listConnections) връща списък с редуващи се стойности. Списъкът ще изглежда като [connectionDestination,connectionSource,connectionDestination,connectionSource]. За да направя нещо с този списък, в идеалния случай бих искал да направя нещо подобно на:

for destination, source in cmds.listConnections():
    print source, destination

Можете, разбира се, просто да повторите всеки друг елемент в списъка, като използвате [::2] и изброяването и източникът ще бъдат индексът+1, но тогава трябва да добавите допълнителни проверки за нечетно номерирани списъци и други неща.

Най-близкото нещо, което съм измислил досега, е:

from itertools import izip
connections = cmds.listConnections()
for destination, source in izip(connections[::2], connections[1::2]):
    print source, destination

Това не е особено важно, тъй като вече имам начини да правя това, което искам. Това просто изглежда като едно от онези неща, за които трябва да има по-добър начин да се направи.


person Mathieson    schedule 05.07.2012    source източник
comment
погледнете тази публикация, може би ще помогне stackoverflow.com/questions/1624883/   -  person Hans Z    schedule 05.07.2012
comment
освен това това, което имате, изглежда като добър начин да го направите. работи ли?   -  person Hans Z    schedule 05.07.2012


Отговори (2)


Можете да използвате следния метод за групиране на елементи от итерируем, взет от документацията за zip():

connections = cmds.listConnections()
for destination, source in zip(*[iter(connections)]*2):
    print source, destination

Или за по-разбираема версия използвайте рецептата за групиране от документацията на itertools:

def grouper(n, iterable, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)
person Andrew Clark    schedule 05.07.2012
comment
О, уау. Отне ми малко време да разбера как работи grouper(). Създаваме списъка args така, че всички аргументи да са препратки към един итератор; по този начин, когато itertools.izip_longest() се опитва да изтегли стойност от всяка последователност, той наистина изтегля следващата стойност от същия итератор! Елегантно и ефективно! - person steveha; 05.07.2012

Всичко, страхотен въпрос и отговор. Бих искал да осигуря друго решение, което трябва да допълни отговора на Андрю Кларк (подпори за използване на itertools!). Неговият отговор връща всяка стойност веднъж по следния начин:

iterable = [0, 1, 2, 3, 4, 5, 6,...] n = 2 grouper(n, iterable, fillvalue=None) --> [(0, 1), (2, 3), (3, 4), (5, 6),...]

В кода по-долу всяка стойност ще се появи в n подпоследователности. Като този:

def moving_window(n, iterable):
  start, stop = 0, n
  while stop <= len(iterable):
      yield iterable[start:stop]
      start += 1
      stop += 1

--> [(0, 1), (1, 2), (2, 3), (3, 4),...]

Често срещано приложение за този тип „движещ се прозорец“ или „ядро“ са подвижните средни стойности в науката и финансите.

Също така имайте предвид, че изявлението за доходност позволява всяка подпоследователност да бъде създадена според нуждите и да не се съхранява в паметта.

person John C. King    schedule 15.07.2015