1

In the code below, how can I use keep using set to have unique values, but also make set keep the order of how the filters are typed in?

>>> filters = ('f1', 'f2')
>>> set((*filters, 'f3'))
{'f1', 'f3', 'f2'} # expected: {'f1', 'f2', 'f3'}
barciewicz
  • 3,511
  • 6
  • 32
  • 72
  • 1
    In python, dict keep insertion order, so you could use a dict, storing the keys and ignoring the values. – Stef Mar 15 '23 at 09:15
  • 2
    Sets are inherently unordered. Use a dict, list or tuple if you need to preserve the order. Without knowing what you're planning on using the set for, it's hard to recommend a specific solution. – Jules SJ Mar 15 '23 at 09:17

2 Answers2

1

Since python3.6/3.7, dict are ordered and retain their insertion order.

So, instead of a set, you can use a dict. Use the keys to store your items, and ignore the values.

>>> filters = ('first', 'second', 'third', 'fourth')
>>> d = dict.fromkeys((*filters, 'fifth'))
>>> d
{'first': None, 'second': None, 'third': None, 'fourth': None, 'fifth': None}
>>> tuple(d)
('first', 'second', 'third', 'fourth', 'fifth')
>>> [*d]
['first', 'second', 'third', 'fourth', 'fifth']

Alternative syntax using zip_longest:

>>> from itertools import zip_longest
>>> 
>>> filters = ('first', 'second', 'third', 'fourth')
>>> d = dict((*zip_longest(filters, ()), ('fifth', None)))
>>> d
{'first': None, 'second': None, 'third': None, 'fourth': None, 'fifth': None}

Alternative syntax using a generator expression:

>>> filters = ('first', 'second', 'third', 'fourth')
>>> d = dict((*((f,()) for f in filters), ('fifth',())))
>>> d
{'first': (), 'second': (), 'third': (), 'fourth': (), 'fifth': ()}
Stef
  • 13,242
  • 2
  • 17
  • 28
1

as stated by others in the comment and answer by @Stef, dictionary is the way to go:

filters = ('f1', 'f2','f3','f4')

list(dict.fromkeys((*filters, 'f5'))  # this will generate only unique as keys are unique and preseve the order as well

#output
['f1', 'f2', 'f3', 'f4', 'f5']
Talha Tayyab
  • 8,111
  • 25
  • 27
  • 44