Получение всех незаполненных строк из списка вложенных списков и кортежей - PullRequest
0 голосов
/ 01 ноября 2018

Есть ли быстрый способ получить уникальные элементы, особенно строки из списка или кортежа вложенных списков и кортежей. Строки типа 'min' и 'max' должны быть удалены. Списки и кортежи могут быть вложены любым возможным способом. Единственный элемент, который всегда будет одинаковым, - это кортежи в ядре ('a', 0,49), которые содержат строки.

Как список или кортеж:

lst1=[[(('a',0,49),('b',0,70)),(('c',0,49))],
     [(('c',0,49),('e',0,70)),(('a',0,'max'),('b',0,100))]]

tuple1=([(('a',0,49),('b',0,70)),(('c',0,49))],
     [(('c',0,49),('e',0,70)),(('a',0,'max'),('b',0,100))]) 

Требуемый выход:

uniquestrings = ['a','b','c','e']

Что я пробовал до сих пор:

flat_list = list(sum([item for sublist in x for item in sublist],()))

Но это не относится к «ядру» вложенного объекта

Ответы [ 3 ]

0 голосов
/ 01 ноября 2018

Это получит любую строку внутри заданной итерации, независимо от положения внутри итерируемой:

def isIterable(obj):
    # cudos: https://stackoverflow.com/a/1952481/7505395
    try:
        _ = iter(obj)
        return True
    except:
        return False

# shortcut
isString = lambda x: isinstance(x,str)

def chainme(iterab):
    # strings are iterable too, so skip those from chaining
    if isIterable(iterab) and not isString(iterab):
        for a in iterab:
            yield from chainme(a)
    else: 
        yield iterab

lst1=[[(('a',0,49),('b',0,70)),(('c',0,49))],
     [(('c',0,49),('e',0,70)),(('a',0,'max'),('b',0,100))]]

tuple1=([(('a',0,49),('b',0,70)),(('c',0,49))],
     [(('c',0,49),('e',0,70)),(('a',0,'max'),('b',0,100))]) 


for k in [lst1,tuple1]:
    # use only strings
    l = [x for x in chainme(k) if isString(x)]
    print(l)
    print(sorted(set(l)))
    print()

Выход:

['a', 'b', 'c', 'c', 'e', 'a', 'max', 'b'] # list
['a', 'b', 'c', 'e', 'max']                # sorted set of list

['a', 'b', 'c', 'c', 'e', 'a', 'max', 'b']
['a', 'b', 'c', 'e', 'max']
0 голосов
/ 01 ноября 2018
import collections

def flatten(l):
    for el in l:
        if isinstance(el, collections.Iterable) and not isinstance(el, (str, bytes)):
            yield from flatten(el)
        else:
            yield el

[x for x in set(list(flatten(lst1))) if str(x).isalpha() if str(x) != "max" and "min"]

Вы можете использовать коды для выравнивания, как определено здесь: Свести нерегулярный список списков

0 голосов
/ 01 ноября 2018
# generative flatten algorithm
def flatten(lst):
    for x in lst:
        if isinstance(x, (list, tuple,)):
            for x in flatten(x):
                yield x
        else:
            yield x

# source list (or tuple)
lst1 = [[(('a', 0, 49), ('b', 0, 70)), (('c', 0, 49))],
        [(('c', 0, 49), ('e', 0, 70)), (('a', 0, 'max'), ('b', 0, 100))]]

# getting elements
lst1 = list(flatten(lst1))[::3]
# >>> ['a', 'b', 'c', 'c', 'e', 'a', 'b']

# delete non-unique elements and sorting result list
lst1 = sorted(list(set(lst1)))
# >>> ['a', 'b', 'c', 'e']
...