Re: use set notation for repr of dict_keys?
On Wed, 24 Feb 2021 at 15:02, Random832 wrote: > On Wed, Feb 24, 2021, at 02:59, Marco Sulla wrote: > > On Wed, 24 Feb 2021 at 06:29, Random832 wrote: > > > I was surprised, though, to find that you can't remove items directly > > > from the key set, or in general update it in place with &= or -= (these > > > operators work, but give a new set object). > > > > This is because they are a view. Changing the key object means you > > will change the underlying dict. Probably not that you want or expect. > > Why wouldn't it be what I want or expect? Java allows exactly this I didn't know this. I like Java, but IMHO it's quite confusing that you can remove a key from a Map using the keys object. In my mind it's more natural to think views as read-only, while changes can be done only using the original object. But maybe my mind has too strict bounds. > [and it's the only way provided to, for example, remove all keys matching a > predicate in a single pass... an operation that Python sets don't support > either] I hope indeed that someday Python can do: filtered_dict = a_dict - a_set -- https://mail.python.org/mailman/listinfo/python-list
Re: use set notation for repr of dict_keys?
On Wed, Feb 24, 2021, at 02:59, Marco Sulla wrote: > On Wed, 24 Feb 2021 at 06:29, Random832 wrote: > > I was surprised, though, to find that you can't remove items directly from > > the key set, or in general update it in place with &= or -= (these > > operators work, but give a new set object). > > This is because they are a view. Changing the key object means you > will change the underlying dict. Probably not that you want or expect. Why wouldn't it be what I want or expect? Java allows exactly this [and it's the only way provided to, for example, remove all keys matching a predicate in a single pass... an operation that Python sets don't support either] > You can just "cast" them into a "real" set object. > > There was a discussion to implement the whole Set interface for dicts. > Currently, only `|` is supported. -- https://mail.python.org/mailman/listinfo/python-list
Re: use set notation for repr of dict_keys?
On Wed, 24 Feb 2021 at 06:29, Random832 wrote: > I was surprised, though, to find that you can't remove items directly from > the key set, or in general update it in place with &= or -= (these operators > work, but give a new set object). This is because they are a view. Changing the key object means you will change the underlying dict. Probably not that you want or expect. You can just "cast" them into a "real" set object. There was a discussion to implement the whole Set interface for dicts. Currently, only `|` is supported. -- https://mail.python.org/mailman/listinfo/python-list
Re: use set notation for repr of dict_keys?
On Wed, Feb 24, 2021 at 4:29 PM Random832 wrote: > > AIUI the keys, values, and items collections have always had the ordering > guarantee that iterating over them while not modifying the underlying > dictionary will give the same order each time [with respect to each other, > and possibly also with respect to iterating over the original dictionary to > obtain the keys] > Correct, on all counts. I believe the old guarantee (before insertion order was maintained) was that *any* change could change the iteration order, but that .items(), .keys(), and .values() (and their iter* counterparts) would always change together. But in practice, I believe this kind of code has always been safe: for key in some_dict: some_dict[key] += 1 I can't find anywhere in the docs that says that changes to *values* (without changing the set of keys) won't change iteration order, but given how common this kind of code is, I would expect that it's at least a de facto guarantee. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: use set notation for repr of dict_keys?
On Sat, Feb 20, 2021, at 15:00, dn via Python-list wrote: > So, the output is not a set (as you say) but nor (as > apparently-indicated by the square-brackets) is it actually a list! To be clear, it is an instance of collections.abc.Set, and supports most binary operators that sets support. I was surprised, though, to find that you can't remove items directly from the key set, or in general update it in place with &= or -= (these operators work, but give a new set object). AIUI the keys, values, and items collections have always had the ordering guarantee that iterating over them while not modifying the underlying dictionary will give the same order each time [with respect to each other, and possibly also with respect to iterating over the original dictionary to obtain the keys] -- https://mail.python.org/mailman/listinfo/python-list
Re: use set notation for repr of dict_keys?
On 20/02/2021 20.25, Wolfgang Stöcher wrote: > Having a dict like > d = {'one': 1, 'two': 2} > the representation of its keys > repr(d.keys()) > gives > "dict_keys(['one', 'two'])" > > But since the keys are unique, wouldn't a representation using the set > notation > be more intuitive, i.e. what about changing the output of > dict_keys.__repr__ to > "dict_keys({'one', 'two'})" > (using curly braces instead of brackets) When considering the data-returned, the logic of formatting as a set makes sense. So, why did the Python-gods decide otherwise? Let's start by asking what it actually is: >>> d = {'one': 1, 'two': 2} >>> repr(d.keys()) "dict_keys(['one', 'two'])" >>> k = d.keys() >>> type( k ) So, the output is not a set (as you say) but nor (as apparently-indicated by the square-brackets) is it actually a list! Not much help there, then. So, let's use help() to see if that helps, hah! (long listing, so not reproduced here). No joy there either. Is it actually one of our 'standard' collections at all? >>> k is dict False >>> k is list False >>> k is set False >>> k is tuple False OK, that makes reasonable sense. Perhaps dict_keys are a sub-class then? >>> isinstance( k, dict ) False >>> isinstance( k, list ) False >>> isinstance( k, set ) False >>> isinstance( k, tuple ) False Still going 'nowhere' fast! It is (apparently) reported as a list, and we'd like to think of it as a set. So, compare help() output with the attributes of list and set (and/or other collections). There are considerable differences (again, not reproduced here due to length). However, still not revealing any answers! If we de-construct the data contained in a dictionary, then as well as the keys, we should consider the values: >>> d {'one': 1, 'two': 2} >>> k = d.keys() >>> k dict_keys(['one', 'two']) >>> v = d.values() >>> v dict_values([1, 2]) Hah, they are (apparently) considered a list as well, but have another distinct type/are another custom-object. Still not making progress though! We've looked at the data/the output and found nothing much! Now, let's totally invert our view of the matter: Instead of deconstructing the original dictionary, consider the purpose of repr()? <<>> #repr Thus, we should be able to take the output of repr() and re-create the original object. Because a dictionary consists of key-value pairs, we will need both 'sets' of components: >>> new_d = dict( zip( k, v ) ) >>> new_d {'one': 1, 'two': 2} Ahah! Now, we realise that whereas a list-like #list data structure maintains the sequence of its elements, a set #set is not required to do so. Thus, if "k" were a set, what is produced on your machine may be different to what happens on mine/no guarantees: Possibly @Wolfgang's machine = >>> k { 'one', 'two' } Possibly @dn's machine = >>> k { 'two', 'one' } Thus no guarantee that when we try to re-combine keys and values they would correspond correctly! - and if we applied the same to data - even worse: combinatorial issue! Web.Refs: #repr: https://docs.python.org/3/reference/datamodel.html#basic-customization #list: and #set: https://docs.python.org/3/reference/datamodel.html#the-standard-type-hierarchy -- Regards, =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: use set notation for repr of dict_keys?
On 2/20/2021 2:25 AM, Wolfgang Stöcher wrote: Having a dict like d = {'one': 1, 'two': 2} the representation of its keys repr(d.keys()) gives "dict_keys(['one', 'two'])" But since the keys are unique, wouldn't a representation using the set notation be more intuitive, i.e. what about changing the output of dict_keys.__repr__ to "dict_keys({'one', 'two'})" (using curly braces instead of brackets) From 3.0 to 3.7?, when dict keys were unordered, that might have made sense. But now that dict keys are insertion ordered, I think the list brackets suggesting a significant key order is better. There is also the issue that representation changes can break code and therefore need substantial reason. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
use set notation for repr of dict_keys?
Having a dict like d = {'one': 1, 'two': 2} the representation of its keys repr(d.keys()) gives "dict_keys(['one', 'two'])" But since the keys are unique, wouldn't a representation using the set notation be more intuitive, i.e. what about changing the output of dict_keys.__repr__ to "dict_keys({'one', 'two'})" (using curly braces instead of brackets) Wolfgang -- https://mail.python.org/mailman/listinfo/python-list
[issue18186] 2.x subprocess contains set notation
New submission from Daniel Farina: I was vendoring subprocess to pick up the change for #16327 when I noticed I could not import it on 2.6. The backwards compatibility claim at the top is 2.2. Included is a tiny patch that uses a semantically equivalent form. -- components: Library (Lib) files: old-set-notation-v1.patch keywords: patch messages: 190953 nosy: Daniel.Farina priority: normal severity: normal status: open title: 2.x subprocess contains set notation versions: Python 2.6 Added file: http://bugs.python.org/file30542/old-set-notation-v1.patch ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue18186 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue18186] 2.x subprocess contains set notation
Berker Peksag added the comment: Python 2.6 only receives security fixes. You can also look at the subprocess32 module: https://pypi.python.org/pypi/subprocess32 -- nosy: +berker.peksag resolution: - invalid stage: - committed/rejected status: open - closed ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue18186 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue18186] 2.x subprocess contains set notation
Daniel Farina added the comment: Then most assuredly the message at the top is out of date. It seems a pity that for this small change that older python versions cannot use the same code verbatim. It reads: # This module should remain compatible with Python 2.2, see PEP 291. -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue18186 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue18186] 2.x subprocess contains set notation
Daniel Farina added the comment: Also, this fix would be for 2.7. My mistake, even though the goal was to import on older Pythons. -- status: closed - open versions: +Python 2.7 -Python 2.6 ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue18186 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue18186] 2.x subprocess contains set notation
Ned Deily added the comment: Your proposed change would still not make the source compatible with Python 2.2 (released over a decade ago) as set() was introduced in 2.4. When the subprocess module was introduced back then, it made sense to maintain compatibility with then-recent releases but it no longer makes sense when Python 2.7 is reaching the end of its life and all previous versions of Python 2 are retired or no longer receive bug fixes. In Python 3, a number of these compatibility claims have been removed from the source, including the one in subprocess. We could do a comment cleanup in the Python 2 source, as well, but at this point it hardly seems worth it. And since we do no testing against previously retired releases, making this code change is no guarantee that the module would really work in any previous version of Python 2.x. That's for you to decide if you are backporting to these unsupported versions. -- nosy: +ned.deily resolution: invalid - out of date status: open - closed ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue18186 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue18186] 2.x subprocess contains set notation
Daniel Farina added the comment: Okay, fair enough, in that case, here's a patch to fix the documentation as to not make incorrect statements. -- status: closed - open Added file: http://bugs.python.org/file30549/fix-subprocess-compat-documentation-v1.patch ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue18186 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue18186] 2.x subprocess contains set notation
Roundup Robot added the comment: New changeset 4b2fdd4dd700 by Ned Deily in branch '2.7': Issue #18186: remove obsolete 2.2 compatibility comment. http://hg.python.org/cpython/rev/4b2fdd4dd700 -- nosy: +python-dev ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue18186 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue18186] 2.x subprocess contains set notation
Changes by Ned Deily n...@acm.org: -- status: open - closed ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue18186 ___ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
{} for set notation
I really like the set notation idea. Now that sets are first class citizens along with dicts, lists and tuples I think they should be used when it makes sense to use them A keyset of a dictionary should be viewed as a set not a list because it is a key_set_ after all. Also sets should get back their traditional notation of '{' and '}', which dictionaries have been in 'borrowing' for all this time in Python. When defining a non-empty set it could be unambiguous to share the notation. So : {1,2,3} is set([1,2,3]) while {1:'a', 2:'b', 3:'c'} could still be the a dictionary. Of course then {1, 2, 3:'b'} would be undefined and would raise an exception or alternatively be equivalent to {1:None, 2:None, 3:'b'} - a dictionary. As far as the set and dictionary notation being confusing it seems that a common notation is actually a _benefit_, after all sets and dictionaries are not that different! A dictionary is a mapping (surgective explicit function?) from a _set_ of keys to a set (actually a bad or multiset in Python) of values. At the same time a set can also be regarded as a degenerate dictionary as in {1:None, 2:None, 3:None}. A similarity of notation does make sense to me. Of course the empty set is the problem since {} could be interpreted ambiguously as both a set or a dictionary. I think it makes sense to give the '{}' notation to the empty _set_ as this will make more sense as far as common sense goes. If the proposal is to have {x} be the a set([x]) then it only makes sense for {} be a set([]). This will break compatibility with old code and that is why it should be in Python 3000 not in 2.x.x The empty dictionary is probably best represented as {:}, it is actually more clear this way as it shows that there is a key and a value separated by ':' and in this case they are both missing so it is an empty dictionary. Also the frozenset, although not used as often, could still probably get its own notation too. For example: 1.({1,2,3}) - a symmetry with tuples, which are also immutable. The problem of a one element tuple i.e. (10,) not (10) will also be present here. So just as there is a need to use a comma to make (10,)=tuple([10]) one would have to use a comma to specify that a tuple is needed and not a a frozenset() but at the same time the ({1,2,3}) could then never be reduced to {1,2,3}. In other words: ({1,2,3},) is tuple({1,2,3}) ({1,2,3}) is a frozenset([1,2,3]) and never just {1,2,3}. This notation would make the parser go 'nuts'. I think the next idea might be better: 2. _{1,2,3}_ - the underscores '_' intuitively could mean that the braces are fixed blocks and will not move to accomodate addition or removal of elements i.e. the fact that the frozenset is immutable. Or perhaps a more verbose _{_1,2,3_}_ would be better, not sure... 3. {|1,2,3|} or maybe |{1,2,3}| - same aesthetic rationale as above, '|'s look like 'fences' that will not allow the braces to 'move', but this would look to much like Ruby's blocks so 1 and 2 might be better. In general a 'set' are a fundamental data structure. It has always been secondary in traditional programming languages. For simplicity in implementation arrays and lists have been used to mimic a set. Now that Python has a built in set it only makes sense to give it its own notation and maybe Python 3000 is just the right time for it. - Nick Vatamaniuc [EMAIL PROTECTED] wrote: From this interesting blog entry by Lawrence Oluyede: http://www.oluyede.org/blog/2006/07/05/europython-day-2/ and the Py3.0 PEPs, I think the people working on Py3.0 are doing a good job, I am not expert enough (so I don't post this on the Py3.0 mailing list), but I agree with most of the things they are agreeing to. Few notes: - input() vanishes and raw_input() becomes sys.stdin.readline(). I think a child that is learning to program with Python can enjoy something simpler: input() meaning what raw_input() means today. - dict.keys() and items() returns a set view This is being discussed here too a lot, I agree that they will just become equivalent to iterkeys() and iteritems(). - dict.values() a bag (multiset) view I think this isn't a good idea, I think bags can be useful but in this situation they make things too much complex. http://www.python.org/dev/peps/pep-3100/#core-language : - Set literals and comprehensions: {x} means set([x]); {x, y} means set([x, y]). {F(x) for x in S if P(x)} means set(F(x) for x in S if P(x)). NB. {range(x)} means set([range(x)]), NOT set(range(x)). There's no literal for an empty set; use set() (or {1}{2} :-). There's no frozenset literal; they are too rarely needed. I like the idea of set literals, but using {1:2} for dicts and {1, 2} for sets may look a bit confusing. And using {} for the empty dict is confusing even more, newbies will use it a lot for empty sets. Maybe the {:} for the empty dict and {} for the empty set are a bit better. Maybe a better syntax can be use a different
Re: {} for set notation
Nick Vatamaniuc wrote: I really like the set notation idea. Now that sets are first class citizens along with dicts, lists and tuples I think they should be used when it makes sense to use them In actual usage, though, how often is it strictly required one uses a set over a list? It is similar to how queue and stack are not in the default namespace. Unless you really need to ensure no one is allowed to make random access changes to your data, a list with push and pop is really all you need. I beleive the same applies in regards to sets. -- http://mail.python.org/mailman/listinfo/python-list
Re: {} for set notation
tic-tacs, But how often does one use a list or a tuple when a set is actually more meaningful? -- Probably more than expected, because traditionally comming from C and in the older Python versions there were no sets. A prime example are the keys of the dictionary. They are a _set_ not a list. If a list is returned by the keys() method, one might assume that somehow there is a special order to the keys. Or, for example, the other day I looked at some of my old code at some point I was gathering values for removal and I was using a list then I was doing if deleteme is not in removelist: removelist.append(deleteme). And I remember doing that more than one time. Looking back I would have used sets a lot more often especially if they had a quick easy notation like {1,2,3}. Another example is typical constant-like parameters. Again coming from Java and C we have been using FLAG1=1, FLAG2=11, FLAG3=12 then setting FLAG=FLAG1|FLAG2. This uses the bit arithmetics along with the bitwise 'or' operator. It is fine for C but in Python it looks odd. What we really want to say is that FLAG={FLAG1, FLAG2, FLAG3}. A new user would be puzzled by FLAG2=11 or how come FLAG2=2 and FLAG3=4?. In general a set is a fundamental datatype. It was fundamental enough to include in Python as a builtin. Even though there was already the dictionary the list and the tuple. For completeness I think a set deserves its own notation. Once it has it, you'd be surprised how many people would more likely to use than if they had to type set([...]). Regards, Nick Vatamaniuc tac-tics wrote: Nick Vatamaniuc wrote: I really like the set notation idea. Now that sets are first class citizens along with dicts, lists and tuples I think they should be used when it makes sense to use them In actual usage, though, how often is it strictly required one uses a set over a list? It is similar to how queue and stack are not in the default namespace. Unless you really need to ensure no one is allowed to make random access changes to your data, a list with push and pop is really all you need. I beleive the same applies in regards to sets. -- http://mail.python.org/mailman/listinfo/python-list
Re: {} for set notation
tac-tics wrote: Nick Vatamaniuc wrote: I really like the set notation idea. Now that sets are first class citizens along with dicts, lists and tuples I think they should be used when it makes sense to use them In actual usage, though, how often is it strictly required one uses a set over a list? A lot. Perhaps you haven't personally encountered many use cases for them, but I assure you that I and others have. It is similar to how queue and stack are not in the default namespace. Not really. set has proven itself to be more generally useful than the other containers; that's why it was promoted to builtin only one release after it was added to the standard library. (IIRC, people on this list were not very enthusiastic about it, since a dict could cover some (not all) of the use cases, but it kind of won people over.) Unless you really need to ensure no one is allowed to make random access changes to your data, a list with push and pop is really all you need. No it isn't. There are several things sets are signifcantly better than lists at: 1. A set ensures there are no duplicate items, which is often very important. 2. Membership testing. a in b is O(N) if b is a list, but O(1) if b is a set. What this means is, on average, testing whether an item is in a list is roughly proportional to the length of the list, whereas testing whether an item is in a set is roughly constant, no matter how big the set it. If you have thousands of items in your collection, using a list is really going to slow things down. 3. Set operations: union, intersection, difference. I use sets a lot, but these operations not as often. However, when the need for them comes up, these methods are absolutely indispensable. Again, maybe you don't encounter the need for them in your programming (or perhaps you do and aren't aware of how sets could help), but many people use them a lot. Carl Banks -- http://mail.python.org/mailman/listinfo/python-list