A collection of some useful list-related functions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | #========================================================================
def sumList(L):
return reduce(lambda x,y:x+y, L)
#========================================================================
def avgList(L):
return reduce(lambda x,y:x+y, L) /(len(L)*1.0)
#========================================================================
def normList(L, normalizeTo=1):
'''normalize values of a list to make its max = normalizeTo'''
vMax = max(L)
return [ x/(vMax*1.0)*normalizeTo for x in L]
#========================================================================
def normListSumTo(L, sumTo=1):
'''normalize values of a list to make it sum = sumTo'''
sum = reduce(lambda x,y:x+y, L)
return [ x/(sum*1.0)*sumTo for x in L]
#========================================================================
def accumList(L, normalizeTo=None):
''' L= [1, 2, 3, 4, 5]: accumList(L)=> [1, 3, 6, 10, 15]
L= [0.25, 0.25, 0.25, 0.25]: accumList(L)=> [0.25, 0.50, 0.75, 1.00]
normalizeTo: set the last number of the returned list to this value
'''
if normalizeTo: LL = normListSumTo(L, sumTo=normalizeTo)
else: LL = L[:]
r = range(1, len(LL))
newList=[LL[0]]
for i in r:
newList.append( newList[-1]+ LL[i] )
return newList
#========================================================================
def findIndex(sortedList, x, indexBuffer=0):
''' Given a sortedList and value x, return the index i where
sortedList[i-1] <= x < sortedList[i]
Which means,
sortedList.insert( findIndex(sortedList, x), x )
will give a sorted list
'''
if len(sortedList)==2:
if x==sortedList[-1]: return indexBuffer+2
elif x>=sortedList[0]: return indexBuffer+1
else:
L = len(sortedList)
firstHalf = sortedList[:L/2+1]
secondHalf = sortedList[(L/2):]
if secondHalf[-1]<=x:
return indexBuffer + len(sortedList)
elif x< firstHalf[0]:
return indexBuffer
else:
if firstHalf[-1] < x:
return findIndex(secondHalf, x, indexBuffer=L/2+indexBuffer)
else:
return findIndex(firstHalf,x, indexBuffer=indexBuffer)
#========================================================================
def randomPickList(L):
''' given a list L, with all values are numbers,
randomly pick an item and return it's index according
to the percentage of all values'''
return findIndex(accumList(L,1), random.random())
#========================================================================
def deepList(LString):
'''
Given string representation of a nested list tree,
return a list containing all the deepest list contents.
For example:
'[[1,[2, 2a]],[[3,3b],4]]'
==> ['2, 2a', '3,3b']
'[[[1,[2, 2a]],[[3,3b],4]],6]'
==> ['2, 2a', '3,3b']
'[[[[a1,a2],out],o1],[o2,o3]]'
==> ['a1,a2', 'o2,o3']
'[[[[[a1,a2], out], [o1,o2]],[o3,o4]],[o5,o6]]'
==> ['a1,a2', 'o1,o2', 'o3,o4', 'o5,o6']
The code: [x.split(']') for x in code.split('[')]
returns something like:
[[''], [''], [''], [''], [''], ['a1,a2', ', out', ', '],
['o1,o2', '', ','], ['o3,o4', '', ','], ['o5,o6', '', '']]
'''
result= [x[0] for x in \
[x.split(']') for x in LString.split('[')] \
if len(x)>1]
if result==['']: result =[]
return result
#========================================================================
def getListStartsWith(aList, startsWith, isStrip=1):
''' for a list: L= ['abcdef', 'kkddff', 'xyz', '0wer'...],
getListStartWith(L, 'kk') will return:
['kkddff', 'xyz', '0wer'...],
getListStartWith(L, 'xy') will return:
['xyz', '0wer'...],
if isStrip: any item ' xyz' will be considered 'xyz'
else: the spaces in ' xyz' count.
'''
tmp = aList[:]
if isStrip: tmp = [x.strip() for x in tmp]
startLineIndex = 0
for i in range(len(tmp)):
if tmp[i].startswith(startsWith):
startLineIndex = i
return aList[startLineIndex:]
#========================================================================
def rezip(aList):
''' d = [[1, 5, 8, 3], [2, 2, 3, 9], [3, 2, 4, 6]]
rezip(d):
[(1, 2, 3), (5, 2, 2), (8, 3, 4), (3, 9, 6)]
If a =[1, 5, 8], b=[2, 2, 3], c=[3, 2, 4]
then it's eazy to: zip(a,b,c) = [(1, 2, 3), (5, 2, 2), (8, 3, 4)]
But it's hard for d = [[1, 5, 8], [2, 2, 3], [3, 2, 4]]
'''
tmp = [ [] for x in range(len(aList[0])) ]
for i in range(len(aList[0])):
for j in range(len(aList)):
tmp[i].append(aList[j][i])
return tmp
#========================================================================
def sumInList(complexList):
''' Given a complexList [ [a1,b1,c1], [a2,b2,c2], [a3,b3,c3] ],
return a list [ a, b, c] where a = a1+a2+a3, etc.'''
d = rezip(complexList)
return [ reduce(lambda x,y:x+y, z) for z in d ]
#========================================================================
def avgInList(complexList):
''' Given a complexList [ [a1,b1,c1], [a2,b2,c2], [a3,b3,c3] ],
return a list [ a, b, c] where a = avg of a1, a2, a3, etc.'''
d = rezip(complexList)
return [ reduce(lambda x,y:x+y, z)/(len(z)*1.0) for z in d ]
|
Among the above, randomPickList() is probably the most useful:
Testing randomPickList():
x= [1, 3, 6] Randomly pick an item from x for 1000 times to see the ratio in x is kept:
y = [0,0,0] for i in range(1000): y[randomPickList(x)]+=1
y=> [112, 300, 588]
Tags: shortcuts
reZip. reZip can be simplified, I think:
I usually call this function 'pivot'.
This returns a list of tupes, rather than a list of lists. If that matters, you could do:
What about splitting a list? Is their an efficient way to split a list into two, equivalent to the code snippet below?