java- reset list iterator to first element of the list
Best would be not using LinkedList
at all, usually it is slower in all disciplines, and less handy. (When mainly inserting/deleting to the front, especially for big arrays LinkedList is faster)
Use ArrayList
, and iterate with
int len = list.size();
for (int i = 0; i < len; i++) {
Element ele = list.get(i);
}
Reset is trivial, just loop again.
If you insist on using an iterator, then you have to use a new iterator:
iter = list.listIterator();
(I saw only once in my life an advantage of LinkedList: i could loop through whith a while loop and remove the first element)
How do you reset an iterator?
The general answer is that you can't reset an iterable in JS. This is, as far as I know, by-design, although I'm not privy to the decision-making process that was used to reach that conclusion.
In your specific case however, you don't want to necessarily reset the iterator, you want to cycle through the array. In that case, you can use the modulo operator as follows:
function nameIterator(names) {
let nextIndex = 0;
return {
next: function() {
nextIndex = (nextIndex + 1) % names.length;
return { value: names[nextIndex], done: false };
}
}
}
Resetting an iterator, which is a map object?
Iterating an iterator/generator consumes the values from it (infinite generators being an exception), meaning that they will no longer be available on future iterations (as you've seen). For a typical iterator/generator in Python, the only true way to "restart" it is to re-initialize it.
>>> sol = map(pow, [1, 2, 3], [4, 5, 6])
>>> list(sol)
[1, 32, 729]
>>> next(sol)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> sol = map(pow, [1, 2, 3], [4, 5, 6])
>>> next(sol)
1
There are ways that you can work with the iterator to make it reusable though, such as with itertools.tee
(as mentioned by one of the answers to the question linked by @JanChristophTerasa), or to convert the iterator into a list, which will persist its data.
itertools.tee
>>> from itertools import tee
>>> sol = map(pow, [1, 2, 3], [4, 5, 6])
>>> a, b = tee(sol, 2)
>>> list(a)
[1, 32, 729]
>>> list(b)
[1, 32, 729]
>>> list(a)
[]
with tee
though, both a
and b
will still be iterators, so you'll have the same problem with them.
Another common way to handle this is with list()
sol = list(map(pow, [1, 2, 3], [4, 5, 6]))
>>> sol
[1, 32, 729]
>>> sol
[1, 32, 729]
Now, sol
is a list of values instead of an iterator, which means you can iterate it as many times as you want - the values will remain there. This does mean you can't use next
with it (in the sense of next(sol)
), but you can get an iterator back from your new list with iter(sol)
if you need an iterator specifically.
Edit
I saw itertools.cycle
mentioned in the comments, which is also a valid option so I thought I might add some info on it here as well.
itertools.cycle
is one of those infinite generators I mentioned at the start. It is still an iterator, but in a way that you'll never run out of values.
>>> from itertools import cycle
>>> sol = map(pow, [1, 2, 3], [4, 5, 6])
>>> infinite = cycle(sol)
>>> for _ in range(5):
... print(next(infinite))
...
1
32
729
1
32
>>>
A few notes on this - after iterating infinite
N times, it will be positioned after whatever the last value was pulled from it. Iterating it again later will resume from that position, not from the start.
Also, and this is very important, do not iterate an infinite generator in an unbounded fashion, like list(infinite)
or for x in infinite:
, or you're gonna have a bad time.
Reset Iterator position to 0 in a nested while-loop
How can I reset
itemIterator
to position 0 without reinitiating it usingitems.iterator()
because that will bring back items removed fromitemIterator
for next iteration.
No, it won't. itemIterator.remove()
removes the item from the collection you got the iterator from, not just the iterator. If you get a new iterator from that collection, it won't have that item on it anymore; you removed it. From the JavaDoc:
Removes from the underlying collection the last element returned by this iterator (optional operation). This method can be called only once per call to
next()
.
(my emphasis)
You can't reset an iterator; just get a new one, within the while
.
Iterator<Event> eventIterator = events.iterator();
while (eventIterator.hasNext()) {
Event event = eventIterator.next();
Iterator<EventItem> itemIterator = items.iterator();
while (itemIterator.hasNext()) {
EventItem item = itemIterator.next();
if (event.getId().equals(item.getEventId())) {
// CLAIMED
itemIterator.remove();
}
}
// If you need to loop a second time for some reason:
itemIterator = items.iterator();
// ...
}
Can iterators be reset in Python?
I see many answers suggesting itertools.tee, but that's ignoring one crucial warning in the docs for it:
This itertool may require significant
auxiliary storage (depending on how
much temporary data needs to be
stored). In general, if one iterator
uses most or all of the data before
another iterator starts, it is faster
to uselist()
instead oftee()
.
Basically, tee
is designed for those situation where two (or more) clones of one iterator, while "getting out of sync" with each other, don't do so by much -- rather, they say in the same "vicinity" (a few items behind or ahead of each other). Not suitable for the OP's problem of "redo from the start".
L = list(DictReader(...))
on the other hand is perfectly suitable, as long as the list of dicts can fit comfortably in memory. A new "iterator from the start" (very lightweight and low-overhead) can be made at any time with iter(L)
, and used in part or in whole without affecting new or existing ones; other access patterns are also easily available.
As several answers rightly remarked, in the specific case of csv
you can also .seek(0)
the underlying file object (a rather special case). I'm not sure that's documented and guaranteed, though it does currently work; it would probably be worth considering only for truly huge csv files, in which the list
I recommmend as the general approach would have too large a memory footprint.
In Python, is it a bad practice to "reset" an iterator when __iter__ is called?
iter
is expected to have no side effects. By violating this assumption, your code breaks all sorts of things. For example, the standard test for whether a thing is iterable:
try:
iter(thing)
except TypeError:
do_whatever()
will reset your file. Similarly, the itertools consume
recipe:
def consume(iterator, n=None):
"Advance the iterator n-steps ahead. If n is None, consume entirely."
# Use functions that consume iterators at C speed.
if n is None:
# feed the entire iterator into a zero-length deque
collections.deque(iterator, maxlen=0)
else:
# advance to the empty slice starting at position n
next(islice(iterator, n, n), None)
will produce an incorrect file position instead of advancing n
records after consume(your_file, n)
. Skipping the first few records with next
before a loop will also fail:
f = MySpecialFile(whatever)
next(f) # Skip a header, or try, anyway.
for record in f:
# We get the header anyway.
uhoh()
Why iterator doesn't have any reset method?
Why?
Because if you force iterator to have a reset method every iterator has to have a reset method. That gives every iterator writer extra work. Plus some iterators are really hard (or really expensive) to reset, and you wouldn't want users to call reset on them. Iterators over files or streams are good examples.
what the best way to move iterator items pointer to the first position?
Create a new iterator. It's rarely more expensive than the reset.
How to reset a loop that iterates over a set?
One way to do so would be by using iterators. You could define an iterator by simply calling iter()
on your set, and call its next
method on each iteration. When the condition is met, you can simply create again the iterator object from the set and repeat the process:
s = {1,2,3,4,5}
s_ = iter(s)
# Just a counter to avoid endless loop
cont = 0
while cont < 10:
try:
i = next(s_)
except StopIteration:
break
# Some condition
if flag == True:
# Reset the iterator when the condition is met
s_ = iter(s)
continue
cont += 1
Related Topics
Create a Newline for Every X Number of Characters
Set Focus to the Next Input Element
Node.Js Document Is Not Defined
Pass Variable from Android to JavaScript Launched in Webview
Show 2 Items Per Row[React Native]
Bootstrap Datepicker Appearing At Incorrect Location in a Modal
Php - Return Confirm Within PHP Issue
Process a Dictionary and Return Each Entry in React
How to Export or Convert Json to Excel in Angularjs
Detect Click on HTML Button Through JavaScript in Android Webview
Why Does Prettier Not Format Code in VS Code
What Does an Exclamation Mark Before a Variable Mean in JavaScript
Reactjs Dynamic Drop Down Populated With Map Function
Disable F5 and Browser Refresh Using JavaScript
How to Convert Date Format from Dd.Mm.Yyyy to Dd/Mm/Yyyy in JavaScript