Это общая форма (как уже было сказано в других ответах)
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.
Вы можете выполнить несколько левых внешних соединений, просто связав вышеупомянутый синтаксис.
ВАЖНОЕ ПРИМЕЧАНИЕ: Вы имеете к [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 + "."
Это даст Вам вывод:
животные: перенос и утка.
заводы: кактус.
механизмы: скоростная моторная лодка и школьный автобус.
Можно ли показать нам код?
пример на документах 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
метод на самом деле просто выполняет итерации через список и каждый раз, когда ключевые изменения он создает новую группу.
Прием neato с groupby к кодированию по длинам серий в одной строке:
[(c,len(list(cgen))) for c,cgen in groupby(some_string)]
даст Вам список 2 кортежей, где первый элемент является символом, и 2-м является количество повторений.
Редактирование: Обратите внимание, что это - то, что отделяется itertools.groupby
от семантики SQL GROUP BY
: itertools не делает (и в целом не может) сортировать итератор заранее, таким образом, группы с тем же "ключом" не объединяются.
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 не будет работать !