Другое событие NullPointerException
возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.
String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals
для гарантированного непустого объекта.
Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null
.
Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.
String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Вам нужна реализация pairwise()
(или grouped()
).
Для Python 2:
from itertools import izip
def pairwise(iterable):
"s -> (s0, s1), (s2, s3), (s4, s5), ..."
a = iter(iterable)
return izip(a, a)
for x, y in pairwise(l):
print "%d + %d = %d" % (x, y, x + y)
Или, в более общем смысле:
from itertools import izip
def grouped(iterable, n):
"s -> (s0,s1,s2,...sn-1), (sn,sn+1,sn+2,...s2n-1), (s2n,s2n+1,s2n+2,...s3n-1), ..."
return izip(*[iter(iterable)]*n)
for x, y in grouped(l, 2):
print "%d + %d = %d" % (x, y, x + y)
В Python 3 вы можете заменить izip
на встроенную функцию zip()
и сбросить import
.
Весь кредит martineau за на его ответ на мой вопрос , я нашел, что это очень эффективно, поскольку он только повторяет один раз над списком и не создает лишних списков в процессе.
Примечание: это не следует путать с рецептом pairwise
в собственной документации itertools
Python , которая дает s -> (s0, s1), (s1, s2), (s2, s3), ...
, как указано из @lazyr в комментариях.
for (i, k) in zip(l[::2], l[1::2]):
print i, "+", k, "=", i+k
zip(*iterable)
возвращает кортеж со следующим элементом каждого итерабельного.
l[::2]
возвращает элемент 1-го, 3-го, 5-го и т. д. списка: первая двоеточие указывает, что срез начинается с начала, потому что за ним нет номера, второй двоеточие требуется только, если вы хотите «шаг в срезе» (в этом случае 2).
l[1::2]
делает то же самое, но начинается во втором элементе списков, поэтому он возвращает элемент 2-го, 4-го, 6-го и т. д. исходного списка.
[number::number]
. полезно для тех, кто не использует python часто
– Alby
26 December 2013 в 23:33
Для любого, кому это может помочь, вот решение аналогичной проблемы, но с перекрывающимися парами (вместо взаимно исключающих пар).
Из документации Python itertools :
from itertools import izip
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)
Или, в более общем смысле:
from itertools import izip
def groupwise(iterable, n=2):
"s -> (s0,s1,...,sn-1), (s1,s2,...,sn), (s2,s3,...,sn+1), ..."
t = tee(iterable, n)
for i in range(1, n):
for j in range(0, i):
next(t[i], None)
return izip(*t)
Мы также можем просто сделать список набором кортежей
l = [(1,2),(3,4)]
l.append((5,6))
for r,c in l:
print r,c
:
1 2
3 4
5 6
Ну, вам нужен набор из 2 элементов, поэтому
data = [1,2,3,4,5,6]
for i,k in zip(data[0::2], data[1::2]):
print str(i), '+', str(k), '=', str(i+k)
Где:
data[0::2]
означает создание набора подмножеств элементов, которые (index % 2 == 0)
zip(x,y)
создает набор кортежей из x и y, которые собирают одинаковые элементы индекса. for i, j, k in zip(data[0::3], data[1::3], data[2::3]):
– lifebalance
26 January 2014 в 17:53
import
не является одним из них.
– abarnert
3 August 2014 в 13:20
Хотя все ответы с использованием zip
верны, я обнаружил, что реализация самой функции приводит к более читаемому коду:
def pairwise(it):
it = iter(it)
while True:
yield next(it), next(it)
Часть it = iter(it)
гарантирует, что it
на самом деле является итератор, а не просто итеративный. Если it
уже является итератором, эта строка не работает.
Использование:
for a, b in pairwise([0, 1, 2, 3, 4, 5]):
print(a + b)
it
является только итератором, а не итерируемым. Другие решения, похоже, полагаются на возможность создания двух независимых итераторов для последовательности.
– skyking
4 September 2015 в 09:32
Если вы заинтересованы в производительности, я сделал небольшой ориентир для сравнения производительности решений, и я включил функцию из одного из моих пакетов: iteration_utilities.grouper
def Johnsyweb(l):
def pairwise(iterable):
"s -> (s0, s1), (s2, s3), (s4, s5), ..."
a = iter(iterable)
return zip(a, a)
for x, y in pairwise(l):
pass
def Margus(data):
for i, k in zip(data[0::2], data[1::2]):
pass
def pyanon(l):
list(zip(l,l[1:]))[::2]
def taskinoor(l):
for i in range(0, len(l), 2):
l[i], l[i+1]
def mic_e(it):
def pairwise(it):
it = iter(it)
while True:
try:
yield next(it), next(it)
except StopIteration:
return
for a, b in pairwise(it):
pass
def MSeifert(it):
for item1, item2 in grouper(it, 2):
pass
from iteration_utilities import grouper
from simple_benchmark import benchmark_random_list
b = benchmark_random_list(
[Johnsyweb, Margus, pyanon, taskinoor, mic_e, MSeifert],
sizes=[2**i for i in range(1, 20)])
b.plot_both(relative_to=MSeifert)
Windows 10 64-разрядный Anaconda Python 3.6
Итак, если вам нужно самое быстрое решение без внешних зависимостей, вам, вероятно, следует просто использовать
Если вы не возражаете против дополнительной зависимости, то grouper
из iteration_utilities
, вероятно, будет немного быстрее, если вы не возражаете против дополнительной зависимости. .
Некоторые из подходов имеют некоторые ограничения, которые здесь не обсуждались.
Например, несколько решений работают только для последовательностей ( это списки, строки и т. д.), например решения Margus / pyanon / taskinoor, которые используют индексирование, в то время как другие решения работают над любым итерационным (то есть последовательностями и генераторами, итераторами), такими как решения Johnysweb / mic_e / my.
Затем Johnysweb также pr ovided решение, которое работает для других размеров, чем 2, в то время как другие ответы не соответствуют (хорошо, iteration_utilities.grouper
также позволяет установить количество элементов в «группу»).
Затем возникает вопрос о том, что должно произойти, если в списке есть нечетное число элементов. Должен ли оставшийся пункт быть уволен? Должен ли список быть дополнен, чтобы сделать его даже размером? Должен ли оставшийся элемент быть возвращен как единый? Другой ответ не затрагивает эту точку напрямую, однако, если я не упускаю из виду что-либо, все они следуют подходу, согласно которому оставшийся элемент должен быть уволен (за исключением ответа на запрос, который фактически вызовет исключение).
С помощью grouper
вы можете решить, что вы хотите сделать:
>>> from iteration_utilities import grouper
>>> list(grouper([1, 2, 3], 2)) # as single
[(1, 2), (3,)]
>>> list(grouper([1, 2, 3], 2, truncate=True)) # ignored
[(1, 2)]
>>> list(grouper([1, 2, 3], 2, fillvalue=None)) # padded
[(1, 2), (3, None)]
Название этого вопроса вводит в заблуждение, похоже, вы ищете последовательные пары, но если вы хотите перебрать множество всех возможных пар, это будет работать:
for i,v in enumerate(items[:-1]):
for u in items[i+1:]:
Ближе всего к написанному вами коду:
l = [1,2,3,4,5,6]
for i,k in zip(l[::2], l[1::2]):
print(str(i), '+', str(k), '=', str(i+k))
Выход:
1+2=3
3+4=7
5+6=11
>>> l = [1,2,3,4,5,6]
>>> zip(l,l[1:])
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
>>> zip(l,l[1:])[::2]
[(1, 2), (3, 4), (5, 6)]
>>> [a+b for a,b in zip(l,l[1:])[::2]]
[3, 7, 11]
>>> ["%d + %d = %d" % (a,b,a+b) for a,b in zip(l,l[1:])[::2]]
['1 + 2 = 3', '3 + 4 = 7', '5 + 6 = 11']
zip
возвращает объект zip
в Python 3, который не подлежит расшифровке. Сначала его нужно преобразовать в последовательность (list
, tuple
и т. Д.), Но "не работает & quot; i> немного растягивается.
– vaultah
25 February 2017 в 15:03
Используйте команды zip
и iter
вместе:
zip(*[iter(l)]*2)
, которые я нашел в документации Pipon 3 zip :
l = [1,2,3,4,5,6]
for i,j in zip(*[iter(l)]*2):
print("{}+{}={}".format(str(i),str(j),str(i+j)))
, что приводит к:
1+2=3
3+4=7
5+6=11
Здесь у нас может быть метод alt_elem
, который может поместиться в ваш цикл for.
def alt_elem(list, index=2):
for i, elem in enumerate(list, start=1):
if not i % index:
yield tuple(list[i-index:i])
a = range(10)
for index in [2, 3, 4]:
print("With index: {0}".format(index))
for i in alt_elem(a, index):
print(i)
Выход:
With index: 2
(0, 1)
(2, 3)
(4, 5)
(6, 7)
(8, 9)
With index: 3
(0, 1, 2)
(3, 4, 5)
(6, 7, 8)
With index: 4
(0, 1, 2, 3)
(4, 5, 6, 7)
Примечание: выше решение может быть неэффективным с учетом операции, выполняемые в func.
вы можете использовать пакет more_itertools .
import more_itertools
lst = range(1, 7)
for i, j in more_itertools.chunked(lst, 2):
print(f'{i} + {j} = {i+j}')
Простое решение.
l = [1, 2, 3, 4, 5, 6] for i in range(0, len(l), 2): print str(l[i]), '+', str(l[i + 1]), '=', str(l[i] + l[i + 1])
((l[i], l[i+1])for i in range(0, len(l), 2))
для генератора, можно легко изменить для более длинных кортежей.
– Basel Shishani
29 July 2015 в 11:30
Извинения за опоздание. Я надеюсь, что это будет еще более элегантный способ сделать это.
a = [1,2,3,4,5,6]
zip(a[::2], a[1::2])
[(1, 2), (3, 4), (5, 6)]
Подумал, что это хорошее место, чтобы поделиться своим обобщением этого при n> 2, который является просто скользящим окном над итерируемым:
def sliding_window(iterable, n):
its = [ itertools.islice(iter, i, None)
for i, iter
in enumerate(itertools.tee(iterable, n)) ]
return itertools.izip(*its)
s -> (s0,s1), (s1,s2), (s2, s3), ...
– Lauritz V. Thaulow 22 March 2011 в 11:13itertools
с тем же именем. Конечно, ваши быстрее ... – Sven Marnach 22 March 2011 в 11:22izip_longest()
вместоizip()
. Например:list(izip_longest(*[iter([1, 2, 3])]*2, fillvalue=0))
- & gt;[(1, 2), (3, 0)]
. Надеюсь это поможет. – Johnsyweb 21 January 2013 в 04:19