Home > Blockchain >  New list of not repeated elements
New list of not repeated elements

Time:05-12

I want to create a function that take a lsit as argument, for example:

list = ['a','b','a','d','e','f','a','b','g','b']

and returns a specific number of list elements ( i chose the number) such that no number occurs twice. For example if i chose 3:

 new_list = ['a','b','d']

I tried the following:

def func(j, list):
    new_list=[]
    for i in list:
        while(len(new_list)<j):
            for k in letters:
                if i != k:
                    new_list.append(i)
                    
                    return new_list

But the function went through infinite loop.

CodePudding user response:

Try this.


lst = ['a','b','a','d','e','f','a','b','g','b']

j = 3

def func(j,list_):
    new_lst = []
    for a in list_:
        if a not in new_lst:
            new_lst.append(a)

    return new_lst[:j]

print(func(j,lst)) # ['a', 'b', 'd']

CodePudding user response:

list is a reserved word in python.

If order of the elements is not a concern then

def func(j, user_list):
    return list(set(user_list))[:j]

CodePudding user response:

it's bad practice to use "list" as variable name

you can solve the problem by just using the Counter lib in python

from collections import Counter
a=['a','b','a','d','e','f','a','b','g','b']

b = list(Counter(a))

print(b[:3])

so your function will be something like that

def unique_slice(list_in, elements):
    new_list = list(Counter(list_in))
    print("New list: {}".format(new_list))
    if int(elements) <= len(new_list):
            return new_list[:elements]
    return new_list

hope it solves your question

CodePudding user response:

As others have said you should not Shadow built-in name 'list'. Because that could lead to many issues. This is a simple problem where you should add to a new list and check if the element was already added.

The [:] operator in python lets you separate the list along an index.

>>>l = [1, 2, 3, 4]
>>>l[:1]
[1]
>>>l[1:]
[2, 3, 4]

lst = ['a', 'b', 'a', 'd', 'e', 'f', 'a', 'b', 'g', 'b']


def func(number, _list):
    out = []
    for a in _list:
        if a not in out:
            out.append(a)

    return out[:number]


print(func(4, lst))  # ['a', 'b', 'd', 'e']

CodePudding user response:

def func(j, mylist):
    # dedup, preserving order (dict is insertion-ordered as a language guarantee as of 3.7):
    deduped = list(dict.fromkeys(mylist))
    # Slice off all but the part you care about:
    return deduped[:j]

If performance for large inputs is a concern, that's suboptimal (it processes the whole input even if j unique elements are found in first j indices out of an input where j is much smaller than the input), so the more complicated solution can be used for maximum efficiency. First, copy the itertools unique_everseen recipe:

from itertools import filterfalse, islice  # At top of file, filterfalse for recipe, islice for your function

def unique_everseen(iterable, key=None):
    "List unique elements, preserving order. Remember all elements ever seen."
    # unique_everseen('AAAABBBCCDAABBB') --> A B C D
    # unique_everseen('ABBCcAD', str.lower) --> A B C D
    seen = set()
    seen_add = seen.add
    if key is None:
        for element in filterfalse(seen.__contains__, iterable):
            seen_add(element)
            yield element
    else:
        for element in iterable:
            k = key(element)
            if k not in seen:
                seen_add(k)
                yield element

now wrap it with islice to only pull off as many elements as required and exiting immediately once you have them (without processing the rest of the input at all):

def func(j, mylist):  # Note: Renamed list argument to mylist to avoid shadowing built-in
    return list(islice(unique_everseen(mylist), j))
  • Related