Here is something totally the opposite of a nice one liner:
A hackish module with a bloated generator. Feel free to comment, so I
can learn the errors of my ways. Try not to be too mean though. Try to
think of the attached file as a demonstration of ideas instead of good
coding practices.
Don't be afraid to mention the good points too.
I tried to send an email with an attachment (to hide my shame) but I
kept getting email rejections.
# =======================================================
# list2dict.py
# list item to dict item generator
# I forget if generators are thread safe
# (e-mail address removed)
# 2011-01 Jan-03
#
def check_slice_bounds(list_len, start, stop, step):
"""Incomplete slice checker."""
# -----------------------------
# force step to be non-None
if step is None:
step = 1
# -----------------------------
# force step to be non-zero
if step == 0:
step = 1
# -----------------------------
# in iterating over list to be converted to dict
# where list == [key, value, key, value] or in case swap==True
# list = [value, key, value, key]
# actual stepping is one for key, and plus one more for value
step = step * 2
# -----------------------------
# force step to be smaller then size of list or -size of list
if step > 0:
if step > list_len:
step = list_len
else:
if step < -list_len:
step = -list_len
# -----------------------------
# force step to be even for key, value iteration
if step % 2 == 1:
if step > 0:
step = step - 1
else:
step = step + 1
# -----------------------------
# set start to default; depending on step direction (+x vs -x)
if start is None:
if step > 0:
start = 0
elif step == 0:
start = 0
stop = start
else:
start = -1
# -----------------------------
# set stop to default; depending on step direction (+x vs -x)
if stop is None:
if step > 0:
stop = list_len-1
elif step == 0:
stop = start
else:
stop = -list_len
# -----------------------------
# convert "start" to equivelent positive index
if start < 0:
if start < -list_len:
raise IndexError("IndexError: list index out of range:",
start)
else:
start = list_len + 1 + start
# -----------------------------
# convert "stop" to equivelent positive index
if stop < 0:
if stop < -list_len:
raise IndexError("IndexError: list index out of range:",
stop)
else:
stop = list_len + 1 + stop
return (start, stop, step)
def gen(lyst, dyct=None, start=None, stop=None, step=None,
swap=False):
"""
lyst == list to convert to dict
dyct == external dict to be updated
start == starting index
stop
step == amount to move index by; usually +1 or -1 (times 2)
could be a float if clever enough.
if step equals zero it is converted to 1 to prevent
an infinite loop.
step will be reset to be an index inbounds of a list len()
swap 2nd item with the first item in the yield
"""
# -----------------------------
# Force into bool True or False from equivelent values
if swap == True: swap = True
else: swap = False
# -----------------------------
# check and set lyst slice/index bounds of start, stop, step
start, stop, step = check_slice_bounds(len(lyst), start, stop,
step)
# -----------------------------
index = start
# -----------------------------
while 0 <= index < len(lyst):
next = index + 1
if next == len(lyst):
value = None
else:
value = lyst[next]
key = lyst[index]
# -----------------------------
# update external dict if given
if dyct is not None:
dyct[key] = value
# -----------------------------
# effectively sway key with value == index, index+1 to index
+1, index
if swap:
newindex = yield (value,key)
else:
newindex = yield (key,value)
# -----------------------------
# process "newindex" variable if caller does a
# gen.send(some_list_index) externally
if newindex is None:
index = index + (step)
elif 0 <= newindex < len(lyst):
# fix this to allow for negative index for negative
stepping
# but don't forget to convert it to its corrosponding
# positive index
index = newindex
else:
# fix this so it doesn't error on index 0
#raise IndexError("Index is out of range:", index)
pass
# -----------------------------
# Ungracefully coerce end of iteration
if step > 0:
if index > stop:
# fix to raise StopIteration
break
else:
if index < stop:
# fix to raise StopIteration
break
# Example usage
testlist = [1, 2, 3, 4, 5, 6, 7, 'a', 8, 'b']
# --------------------
d = {}
e = {y[0]:y[1] for y in gen(testlist,d)}
print d
print d
print 'next demo1'
# --------------------
d = {}
e = {y[1]:y[0] for y in gen(testlist,d)}
f = {y[0]:y[1] for y in gen(testlist,d, swap=True)}
print d
print e
print f
print 'next demo2'
# --------------------
d = {}
for x in gen(testlist,d):
print x
print d
print 'next demo3'
# --------------------
d = {}
e = [y for y in gen(testlist,d,swap=True)]
print d
print e
print 'next demo4'
# --------------------
d = {}
e = gen(testlist,d)
try:
while e.next(): pass
except:
pass
print d
#print 'next demo'