I’ve come across quite a few instances when using Python in Maya where I was expecting a flat list after querying a selection. However, Maya has the tendency to return a component selection like this:

# Result: 
[u'pSphere1.f[281:286]',
 u'pSphere1.f[300:308]',
 u'pSphere1.f[310:316]',
 u'pSphere1.f[320:359]',
 u'pSphere1.f[380:399]'] # 

You can’t use default for loops to iterate over every face in the list. I used to get around this by first selecting the non-flattened list and then running

pm.ls(selection=True, flatten=True)

But this is messy and adds an extra operation, which slows down your script.

This handy little function does some string manipulation to return a list that’s been flattened as a list of strings or PyNodes

import pymel.core as pm
import re

def flatten_selection_list(selection_list, as_pynodes=False):
    flat_list = []
    for each in selection_list:
        if not ":" in each:
            flat_list.append(each)
            continue

        begin, end = re.findall(r'\[(.*?)\]', each)[0].split(":")
        base_part = each.split("[")[0]

        for number in range(int(begin), int(end) + 1):
            if as_pynodes:
                flat_list.append(pm.PyNode("%s[%s]" % (base_part, number)))
            else:
                flat_list.append("%s[%s]" % (base_part, number))

    return flat_list