40 from debug_tools
import getLogger
46 log = getLogger( 127-4, __name__ )
51 Dynamically creates creates a unique iterable which can be used one time. 53 Why have an __iter__ method in Python? 54 https://stackoverflow.com/questions/36681312/why-have-an-iter-method-in-python 57 def __init__(self, data_container, iterable_access, empty_slots, end_index=None, filled_slots=set()):
59 Receives a iterable an initialize the object to start an iteration. 61 @param `iterable_access` a function pointer to function which returns the next element given its index 62 @param `end_index` it must be a list with one integer element 63 @param `empty_slots` it must be a set with indexes of free place to put new elements 86 Return the total length of this container. 92 Resets the current index and return a copy if itself for iteration. 99 Called by Python automatically when iterating over this set and python wants to know the 100 next element to iterate. Raises `StopIteration` when the iteration has been finished. 102 How to make a custom object iterable? 103 https://stackoverflow.com/questions/21665485/how-to-make-a-custom-object-iterable 104 https://stackoverflow.com/questions/4019971/how-to-implement-iter-self-for-a-container-object-python 110 while current_index
in empty_slots
or current_index
in filled_slots:
123 Raise the exception `StopIteration` to stop the current iteration. 129 Return a nice string representation of this iterable. 134 representation.append( str( item ) )
136 return "{%s}" % (
", ".join( representation ) )
141 A `dict()` like object which allows to dynamically add and remove items while iterating over 142 its elements as in `for element in dynamic_set` 144 https://wiki.python.org/moin/TimeComplexity 145 https://stackoverflow.com/questions/4014621/a-python-class-that-acts-like-dict 148 def __init__(self, initial=None, is_set=False, emquote=False, index=False):
150 Fully initializes and create a new dictionary. 152 @param `initial` is a dictionary used to initialize it with new values. 190 if isinstance( initial, dict ):
192 for key, value
in initial.items():
200 Return a full representation of all public attributes of this object set state for 203 return get_representation( self )
207 Return a nice string representation of this collection. 214 get_key =
lambda: emquote_string( key )
217 get_key =
lambda: key
220 get_index =
lambda:
"{}, {}".format(
get_key(), index )
226 return str( self.
keys() )
231 for index
in range( 0, len( keys_list ) ):
233 if index
not in empty_slots:
234 key = keys_list[index]
235 representation.append(
"%s: %s" % ( get_index(), values_list[index] ) )
237 return "{%s}" %
", ".join( representation )
241 Determines whether this dictionary contains or not a given `key`. 247 Return the total length of this set. 253 Return a iterable for the keys elements of this collection when calling its object as a 256 `how_many_times` is for how many iterations it should keep ignoring the new items. 262 Called by Python automatically when iterating over this set and python wants to start 263 the iteration process. 265 Why have an __iter__ method in Python? 266 https://stackoverflow.com/questions/36681312/why-have-an-iter-method-in-python 272 Given a `key` and `item` add it to this dictionary as a non yet iterated item, replacing 273 the existent value. It a iteration is running, and the item was already iterated, then 274 it will be updated on the `niterated_items` dict. 278 if key
in items_dictionary:
279 item_index = items_dictionary[key]
287 free_slot = empty_slots.pop()
290 values_list[free_slot] = value
294 free_slot = len( values_list )
295 values_list.append( value )
302 Given a `key` returns its existent value. 309 Given a `key` deletes if from this dict. 313 item_index = items_dictionary[key]
316 del items_dictionary[key]
320 Fix the the outdated indexes on the internal lists after their dictionary removal, 321 keeping the items original ordering O(n). 330 for key, value_index
in items_dictionary.items():
332 items_dictionary[key] = new_index
333 clean_keys.append( key )
334 clean_values.append( values_list[value_index] )
342 Fix the the outdated indexes on the internal lists after their dictionary removal. 343 keeping the items original ordering O(k), where `k` is length of `self.empty_slots`. 351 empty_slot = empty_slots.pop()
352 list_length = len( keys_list )
353 key = keys_list.pop()
355 keys_list[empty_slot] = key
356 values_list[empty_slot] = values_list.pop()
359 if last_slot >= list_length:
360 last_slot = last_slot
363 del keys_list[last_slot:]
364 del values_list[last_slot:]
366 def keys(self, how_many_times=-1):
368 Return a DynamicIterable over the keys stored in this collection. 370 `how_many_times` is for how many iterations it should keep ignoring the new items. 376 Return a DynamicIterable over the values stored in this collection. 378 `how_many_times` is for how many iterations it should keep ignoring the new items. 384 Return a DynamicIterable over the (key, value) stored in this collection. 386 `how_many_times` is for how many iterations it should keep ignoring the new items. 392 Given a `index` returns its corresponding key. 398 Given a `index` returns its corresponding value. 404 Given a `index` returns its corresponding (key, value) pair. 410 Get fully configured iterable given the getter `target_generation(index)` function. 412 `how_many_times` is for how many iterations it should keep ignoring the new items. 432 If called before start iterating over this dictionary, it will not iterate over the 433 new keys added until the current iteration is over. 435 `how_many_times` is for how many iterations it should keep ignoring the new items. 438 if how_many_times > 0:
450 Initialize a dictionary with None default value, acting like a indexed set. 458 Add a new element to the end of the list. 464 Remove new `element` anywhere in the container. 470 Add a new element to the end of the list. 476 Remove new `element` anywhere in the container. 485 Return a deep copy of this collection. 487 return copy.deepcopy( self )
491 Remove all items from this dict.