Почему генератор не идентичен пониманию в 2D понимании

Какова логика между одним генератором, создающим одномерный массив, и другим двумерным массивом в следующих выражениях (версия 0.6.2):

julia> collect((a,b,c) for (a,b) in ((i,j) for i in 1:2 for j in 3:4), c in 5:6)
8-element Array{Tuple{Int64,Int64,Int64},1}:
 (1, 3, 5)
 (1, 4, 5)
 (2, 3, 5)
 (2, 4, 5)
 (1, 3, 6)
 (1, 4, 6)
 (2, 3, 6)
 (2, 4, 6)

julia> collect((a,b,c) for (a,b) in [(i,j) for i in 1:2 for j in 3:4], c in 5:6)
4×2 Array{Tuple{Int64,Int64,Int64},2}:
 (1, 3, 5)  (1, 3, 6)
 (1, 4, 5)  (1, 4, 6)
 (2, 3, 5)  (2, 3, 6)
 (2, 4, 5)  (2, 4, 6)

Единственное отличие заключается в замене генератора в первом выражении на понимание во втором выражении.

1 ответ

Решение

((i,j) for i in 1:2 for j in 3:4)а также [(i,j) for i in 1:2, j in 3:4] анализируются выражения с окончательным flatten операция. Выражение [(i,j) for i in 1:2, j in 3:4] собирается в вектор, дающий его iteratorsizeHasShape так что он ведет себя хорошо в продуктах.

Base.iteratorsize(f(i,j) for i in 1:2 for j in 3:4) в общем есть SizeUnknown потому что мы не знаем тип возвращаемого значенияf и операторы в продуктах с SizeUnknown сделать весь продукт SizeUnknown и, следовательно, плоский, когда собраны.

Вы также можете искать

julia> collect((a,b,c) for (a,b) in ((i,j) for i in 1:2, j in 3:4), c in 5:6)
2×2×2 Array{Tuple{Int64,Int64,Int64},3}

julia> collect((a,b,c) for (a,b) in [(i,j) for i in 1:2, j in 3:4], c in 5:6)
2×2×2 Array{Tuple{Int64,Int64,Int64},3}:

(при формировании первого генератора не происходит сглаживания, и все проходит нормально).

Редактировать: я думаю сейчас Base.iteratorsize(f(i,j) for i in 1:2 for j in 3:4) может быть HasShapeЯ попробую добавить это поведение к flatten,

Другие вопросы по тегам