Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.
Например, ниже - класс ученика, который будет использовать его в нашем коде.
public class Student {
private int id;
public int getId() {
return this.id;
}
public setId(int newId) {
this.id = newId;
}
}
Приведенный ниже код дает вам исключение с нулевым указателем.
public class School {
Student obj_Student;
public School() {
try {
obj_Student.getId();
}
catch(Exception e) {
System.out.println("Null Pointer ");
}
}
}
Поскольку вы используете Obj_Student
, но вы забыли инициализировать его, как в правильном коде, показанном ниже:
public class School {
Student obj_Student;
public School() {
try {
obj_Student = new Student();
obj_Student.setId(12);
obj_Student.getId();
}
catch(Exception e) {
System.out.println("Null Pointer ");
}
}
}
Это потому, что data
- итератор, вы можете использовать итератор только один раз. Например:
lst = [1, 2, 3]
it = iter(lst)
next(it)
=> 1
next(it)
=> 2
next(it)
=> 3
next(it)
=> StopIteration
Если мы перемещаем некоторые данные с помощью цикла for
, последний StopIteration
приведет к его завершению в первый раз. Если мы снова попытаемся перебрать его , мы будем получать исключение StopIteration
, потому что итератор уже был использован.
Теперь для второго вопроса: что делать, если нам do нужно переходить через итератор более одного раза? Простым решением было бы создать список с элементами, и мы можем проходить его столько раз, сколько необходимо. Это все в порядке, если в списке несколько элементов:
data = list(db[3])
Но если есть много элементов, лучше создать независимые итераторы, используя tee()
:
import itertools
it1, it2 = itertools.tee(db[3], n=2) # create as many as needed
Теперь мы можем поочередно перебирать по очереди:
for e in it1:
print("doing this one time")
for e in it2:
print("doing this two times")
Как только итератор исчерпан, он больше ничего не даст.
>>> it = iter([3, 1, 2])
>>> for x in it: print(x)
...
3
1
2
>>> for x in it: print(x)
...
>>>
list
, tuple
). Затем выполните итерацию объекта последовательности. (Только если размер csv не огромен)
– falsetru
16 August 2014 в 04:56
csv_file_object.seek(0)
– falsetru
16 August 2014 в 04:56
Я хочу выполнить ответ @ ÓscarLópez для тех, кто ищет решение в 2017 году и использует python 2.7 или 3.
Метод tee () теперь не принимает аргументов ключевых слов и ждет второго аргумента целое число, а не ключевое слово. Это правильный способ использования tee ():
import itertools
it1, it2 = itertools.tee(db[3], 2)
it.next()
подходит для этого примера, поскольку вы можете себе представить, что методnext
каким-то образом изменяетit
, чтобы отслеживать то, что было получено (конечно, с большим количеством объектов, это «отслеживание» или вычисление из следующего значения возвращается в C-коде). Однако, как правило, при написании кода лучше использоватьnext(it)
, если вам не нужно поддерживать действительно старые версии python. Это передовая совместимость с python3.x, гдеit.next()
переименованit.__next__()
... – mgilson 16 August 2014 в 04:52data = list(db[3])
. Теперь вы сможете пересекатьdata
столько раз, сколько необходимо, потому что мы создали список с ним. – Óscar López 16 August 2014 в 04:57tee
: «Этот itertool может потребовать значительного вспомогательного хранилища (в зависимости от того, сколько временных данных необходимо сохранить). В общем случае, если один итератор использует большинство или все данные перед запуском другого итератора, быстрее использовать список () вместо tee (). & Quot; Поэтому, если вы используетеit1
иit2
, как вы в этом примере, вы вряд ли получите какую-либо реальную выгоду изtee
(хотя, возможно, некоторые дополнительные накладные расходы). – svk 16 August 2014 в 20:39