简体   繁体   中英

python : group elements together in list

I'm currently working with itertools to create and return a list whose elements are lists that contain the consecutive runs of equal elements of the original list.

import itertools
it = [1, 1, 5, 5, 5, 'test', 'test', 5]

new = len(it)
for a in range(new):
  return [list(k) for a, k in itertools.groupby(it)] 

For the above example the result is:

[[1, 1], [5, 5, 5], ['test', 'test'], [5]]

Can I achieve this without using itertools ?

To be honest a simple for loop could make this work, you don't even have to import itertools .

The simplest way to do this is by using this:

it = [1, 1, 5, 5, 5, 'test', 'test', 5]
result = []
for (i, x) in enumerate(it):
  if i < 1 or type(x) != type(it[i - 1]) or x != it[i - 1]:
    result.append([x])
  else:
    result[-1].append(x)
print(result)

Or, in function form:

def type_chunk(it):
  result = []
  for (i, x) in enumerate(it):
    if i < 1 or type(x) != type(it[i - 1]) or x != it[i - 1]:
      result.append([x])
    else:
      result[-1].append(x)
  return result

You would then use the function like this:

print(type_chunk([1, 1, 5, 5, 5, 'test', 'test', 5]))

You could even skip the type checking and only look for equal values:

def type_chunk(it):
  result = []
  for (i, x) in enumerate(it):
    if i < 1 or x != it[i - 1]:
      result.append([x])
    else:
      result[-1].append(x)
  return result

Good luck.

You can pair adjacent items by zipping the list with itself but with a padding of float('nan') since it can't be equal to any object, and then iterate through the zipped pairs to append items to last sub-list of the output list, and add a new sub-list when the adjacent items are different:

output = []
for a, b in zip([float('nan')] + it, it):
    if a != b:
        output.append([])
    output[-1].append(b)

output becomes:

[[1, 1], [5, 5, 5], ['test', 'test'], [5]]

You could have a look at the function in itertools to see how they are doing it.

Here is one way which shows the logic clearly (can be further reduced):

def i_am_itertool():
    it = [1, 1, 5, 5, 5, 'test', 'test', 5]
    ret = []

    temp = []
    last = it[0]
    for e in it:
        if e == last:
            temp.append(e)
        else:
            ret.append(temp)  # Add previous group
            temp = [e]  # Start next group
            last = e
    ret.append(temp)  # Add final group
    return ret

print(i_am_itertool())

Output:

 [[1, 1], [5, 5, 5], ['test', 'test'], [5]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM