Как я могу использовать Python itertools.groupby ()?

Это общая форма (как уже было сказано в других ответах)

var c =
    from a in alpha
    join b in beta on b.field1 equals a.field1 into b_temp
    from b_value in b_temp.DefaultIfEmpty()
    select new { Alpha = a, Beta = b_value };

Однако вот объяснение, которое, я надеюсь, прояснит, что это на самом деле означает!

join b in beta on b.field1 equals a.field1 into b_temp

по существу создает отдельный набор результатов b_temp, который эффективно включает в себя нулевые «строки» для записей в правой части (записи в «b»).

Затем следующая строка:

from b_value in b_temp.DefaultIfEmpty()

.. итерации по этому набору результатов, установив значение по умолчанию для «строки» справа, и установив результат строки правой стороны, присоединитесь к значению «b_value» (то есть значение, которое находится на правая сторона, если есть соответствующая запись, или «null», если нет).

Теперь, если правая сторона является результатом отдельного запроса LINQ, она будет состоять из анонимных типов , который может быть только «чем-то» или «нулевым». Однако, если это перечислимо (например, List - где MyObjectB - это класс с 2 полями), тогда можно указать, какие значения по умолчанию для него используются «null»:

var c =
    from a in alpha
    join b in beta on b.field1 equals a.field1 into b_temp
    from b_value in b_temp.DefaultIfEmpty( new MyObjectB { Field1 = String.Empty, Field2 = (DateTime?) null })
    select new { Alpha = a, Beta_field1 = b_value.Field1, Beta_field2 = b_value.Field2 };

гарантирует, что «b» сам по себе не является нулевым (но его свойства могут быть пустыми, используя заданные по умолчанию значения null, которые вы указали), и это позволяет вам проверять свойства b_value, не получая исключение нулевой ссылки для b_value. Обратите внимание, что для нулевой даты DateTime тип (DateTime?), То есть «nullable DateTime», должен быть указан как «Тип» нулевого значения в спецификации для «DefaultIfEmpty» (это также относится к типам, которые не являются «изначально» 'nullable, например double, float.

Вы можете выполнить несколько левых внешних соединений, просто связав вышеупомянутый синтаксис.

446
задан jmunsch 6 August 2014 в 21:34
поделиться

4 ответа

ВАЖНОЕ ПРИМЕЧАНИЕ: Вы имеете к [1 134], сортируют Ваши данные сначала.

<час>

первая часть не добиралась, то, что в конструкции в качестве примера

groups = []
uniquekeys = []
for k, g in groupby(data, keyfunc):
   groups.append(list(g))    # Store group iterator as a list
   uniquekeys.append(k)

k текущий ключ группировки, и g итератор, который можно использовать для итерации по группе, определенной тем ключом группировки. Другими словами, groupby сам итератор возвращает итераторы.

Вот пример этого, с помощью более ясных имен переменной:

from itertools import groupby

things = [("animal", "bear"), ("animal", "duck"), ("plant", "cactus"), ("vehicle", "speed boat"), ("vehicle", "school bus")]

for key, group in groupby(things, lambda x: x[0]):
    for thing in group:
        print "A %s is a %s." % (thing[1], key)
    print " "

Это даст Вам вывод:

перенос А является животным.
утка А является животным.

кактус А является растением.

скоростная моторная лодка А является механизмом.
школьный автобус А является механизмом.

В этом примере, things список кортежей, где первый объект в каждом кортеже является группой, второй объект принадлежит.

groupby() функция берет два аргумента: (1) данные для группировки и (2) функция для группировки его с.

Здесь, lambda x: x[0] говорит groupby() использовать первый объект в каждом кортеже как группирующийся ключ.

В вышеупомянутом for оператор, groupby возвраты три (ключ, итератор группы) пары - однажды для каждого уникального ключа. Можно использовать возвращенный итератор для итерации по каждому отдельному объекту в той группе.

Вот немного отличающийся пример с теми же данными, с помощью понимания списка:

for key, group in groupby(things, lambda x: x[0]):
    listOfThings = " and ".join([thing[1] for thing in group])
    print key + "s:  " + listOfThings + "."

Это даст Вам вывод:

животные: перенос и утка.
заводы: кактус.
механизмы: скоростная моторная лодка и школьный автобус.

602
ответ дан Mateen Ulhaq 7 August 2014 в 08:34
поделиться
  • 1
    Привет спасибо Ericharlow за Вашу ценную справку.. спасибо много. Ваше решение работает на меня. Я искал это решение с долгого времени.. Теперь единственная проблема состоит в том, что мой список подменю появляется в верхний угол справа. не прибытие регулярным.. Я хотел отобразить его ниже своей строки меню.. Как переместить его в надлежащее местоположение.. thankx снова для справки.. – nilkash 2 March 2013 в 16:49

Можно ли показать нам код?

пример на документах Python довольно прост:

groups = []
uniquekeys = []
for k, g in groupby(data, keyfunc):
    groups.append(list(g))      # Store group iterator as a list
    uniquekeys.append(k)

Так в Вашем случае, данные являются списком узлов, keyfunc - то, куда логика Вашей функции критериев идет и затем groupby() группы данные.

необходимо стараться , сортируют данные по критериям перед вызовом groupby, или они не будут работать. groupby метод на самом деле просто выполняет итерации через список и каждый раз, когда ключевые изменения он создает новую группу.

72
ответ дан Kevin Guan 7 August 2014 в 08:34
поделиться
  • 1
    другая проблема состоит в том, что это не работающий над более старой версией устройств на базе Android это выполняет того слушателя щелчка, но не показ моих подменю. Как решить это также. Ли библиотека Sherlock, поддерживающая это или нет. спасибо... – nilkash 2 March 2013 в 17:04

Прием neato с groupby к кодированию по длинам серий в одной строке:

[(c,len(list(cgen))) for c,cgen in groupby(some_string)]

даст Вам список 2 кортежей, где первый элемент является символом, и 2-м является количество повторений.

Редактирование: Обратите внимание, что это - то, что отделяется itertools.groupby от семантики SQL GROUP BY: itertools не делает (и в целом не может) сортировать итератор заранее, таким образом, группы с тем же "ключом" не объединяются.

38
ответ дан nimish 7 August 2014 в 08:34
поделиться
  • 1
    @ericharlow не работа для меня, menu.performIdentifierAction(menuFil.getItemId(),0) всегда возвращают false, и подменю не показывает, никакая справка – Mani 30 October 2013 в 13:52

@CaptSolo, я попробовал ваш пример, но он не сработал.

from itertools import groupby 
[(c,len(list(cs))) for c,cs in groupby('Pedro Manoel')]

Вывод:

[('P', 1), ('e', 1), ('d', 1), ('r', 1), ('o', 1), (' ', 1), ('M', 1), ('a', 1), ('n', 1), ('o', 1), ('e', 1), ('l', 1)]

Как видите, здесь два «о» и два «е», но они попали в отдельные группы. Именно тогда я понял, что вам нужно отсортировать список, переданный функции groupby. Итак, правильное использование будет:

name = list('Pedro Manoel')
name.sort()
[(c,len(list(cs))) for c,cs in groupby(name)]

Вывод:

[(' ', 1), ('M', 1), ('P', 1), ('a', 1), ('d', 1), ('e', 2), ('l', 1), ('n', 1), ('o', 2), ('r', 1)]

Просто помню, если список не отсортирован, функция groupby не будет работать !

7
ответ дан 22 November 2019 в 22:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: