1

I want to append rows of digits in the form of one long string to be appended to a list inside of a list based upon their row. For example, I know ahead of time that each row has 4 digits that can only go up to 99 from 01, and there is a total of 3 rows. How would you got through the string, turn each number into an int and put it in the correct list to show what row it is in?

myStr = "01 02 03 04 11 12 13 14 21 22 23 24"
myList = [[01, 02, 03, 04],[11, 12, 13, 14],[21, 22, 23, 24]]

I need to take in hundreds of these data points into rows, but to understand the concept I'm staying small in the example. I'm not looking for the most concise and professional way to do handle the problem, just a method that reads easy would be better.

Monte Carlo
  • 447
  • 2
  • 6
  • 14

7 Answers7

1

This is what I would do...

numDigits = 4 #Number of digits per row
a = [int(val) for val in myStr.split()]
myList = []
for i in arange(0, len(a), numDigits):
    myList.append(a[i:i+numDigits])

Hope this helps!

A.Wan
  • 1,818
  • 3
  • 21
  • 34
0

This stores all the elements of the rows as strings since you wanted elements like 01 in your output. Since you just wanted simple/easy to read, this is probably fine.

nums = myStr.split(' ')

myList[]
li=[]

int i = 0;
for n in nums:
    if i == 4:
        i = 0
        myList.append(list)
        li= []
    li.append(n)
    i += 1
xgord
  • 4,606
  • 6
  • 30
  • 51
0
myStr = "01 02 03 04 11 12 13 14 21 22 23 24"
myStr= [int(n) for n in myStr.split()]
myList=[]
for i in xrange(0,len(myStr),4):
    myList.append(myStr[i:i+4])

Or, instead of the for loop, you can use list comprehension again.

myList=[myStr[i:i+4] for i in xrange(0,len(myStr),4)]
seth
  • 1,778
  • 16
  • 17
0

Use zip:

>>> myStr = "01 02 03 04 11 12 13 14 21 22 23 24"
>>> n=4
>>> myList=[list(t) for t in zip(*[(int(x) for x in myStr.split())]*n)]
>>> myList
[[1, 2, 3, 4], [11, 12, 13, 14], [21, 22, 23, 24]]

or

>>> myList=map(list,zip(*[(int(x) for x in myStr.split())]*n))

If you do not mind if the inner elements are tuples vs lists, you can do this:

>>> zip(*[(int(x) for x in myStr.split())]*n)
[(1, 2, 3, 4), (11, 12, 13, 14), (21, 22, 23, 24)]

Zip will truncate any incomplete groups. If there is possibility that your your rows are uneven, use a slice:

>>> myList=map(int,myStr.split())
>>> n=5
>>> [myList[i:i+n] for i in range(0,len(myList),n)]   # use xrange on Py 2k...
[[1, 2, 3, 4, 11], [12, 13, 14, 21, 22], [23, 24]]

If you want an intertools recipe, use the grouper recipe:

>>> from itertools import izip_longest
def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

>>> map(list,grouper(map(int,myStr.split()),4))
[[1, 2, 3, 4], [11, 12, 13, 14], [21, 22, 23, 24]]
dawg
  • 98,345
  • 23
  • 131
  • 206
0

Good answers already. Here's a methodical approach, if you're not comfortable with list comprehensions and xrange:

# get or build your string
myStr = "01 02 03 04 11 12 13 14 21 22 23 24"

#set a group size
GROUP_SZ = 4

item_list=myStr.split(' ')
groups= len(item_list)
chunks=[]

for j in range(groups/GROUP_SZ):
    slice=item_list[:GROUP_SZ]
    del item_list[:GROUP_SZ]
    chunks.append(slice)

# account for left over bits, if myStr is not a multiple of GROUP_SZ
if len(item_list) > 0:
   chunks.append( item_list)

Then chunks contains what you want, and any left over bits if your original string is not an integer multiple of your group size.

RossGK
  • 515
  • 2
  • 7
  • 19
  • Why are you deleting that element, why does it magically turn this: `[['01', '02', '03', '04'], ['01', '02', '03', '04'], ['01', '02', '03', '04'], ['01', '02', '03', '04', '11', '12', '13', '14', '21', '22', '23', '24']] into [['01', '02', '03', '04'], ['11', '12', '13', '14'], ['21', '22', '23', '24']]` ? – Monte Carlo Jul 12 '13 at 15:44
0

I would probably do this.

def gridify(s, cols):
    ls = map(int, s.split())
    return map(list, zip(*[iter(ls)]*cols))

You can do without the last map if you're ok with a list of tuples. Before I learned of the idiom of using zip, I would have probably used slicing, another idiom for grouping elements from a sequence.

def gridify(s, cols):
    flatList = map(int, s.split())
    return [flatList[x:x+cols] for x in range(0, len(flatList), cols)]

If you're looking for "a method that reads easy", I think this should do.

def gridify(s, rows, cols):
    flatList = s.split()
    gridList = []
    for r in range(rows):
        rowList = []
        for c in range(cols):
            ind = (r * rows) + c
            val = flatList[ind]
            rowList.append(int(val))
        gridList.append(rowList)
    return gridList
RussW
  • 427
  • 4
  • 11
0
import re

myStr = "01 02 03 04 11 12 13 14 21 22 23 24"

n = 4
print [map(int,x)
       for x in re.findall(n *('(\d\d?) *'),myStr)]

Also, on the same idea

n = 4

def fff(x):
    return map(int,x)

print map(fff, re.findall(n *('(\d\d?) *'),myStr))
eyquem
  • 26,771
  • 7
  • 38
  • 46