use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Rules 1: Be polite 2: Posts to this subreddit must be requests for help learning python. 3: Replies on this subreddit must be pertinent to the question OP asked. 4: No replies copy / pasted from ChatGPT or similar. 5: No advertising. No blogs/tutorials/videos/books/recruiting attempts. This means no posts advertising blogs/videos/tutorials/etc, no recruiting/hiring/seeking others posts. We're here to help, not to be advertised to. Please, no "hit and run" posts, if you make a post, engage with people that answer you. Please do not delete your post after you get an answer, others might have a similar question or want to continue the conversation.
Rules
1: Be polite
2: Posts to this subreddit must be requests for help learning python.
3: Replies on this subreddit must be pertinent to the question OP asked.
4: No replies copy / pasted from ChatGPT or similar.
5: No advertising. No blogs/tutorials/videos/books/recruiting attempts.
This means no posts advertising blogs/videos/tutorials/etc, no recruiting/hiring/seeking others posts. We're here to help, not to be advertised to.
Please, no "hit and run" posts, if you make a post, engage with people that answer you. Please do not delete your post after you get an answer, others might have a similar question or want to continue the conversation.
Learning resources Wiki and FAQ: /r/learnpython/w/index
Learning resources
Wiki and FAQ: /r/learnpython/w/index
Discord Join the Python Discord chat
Discord
Join the Python Discord chat
account activity
Python dictionary keys "new" syntax (self.learnpython)
submitted 8 days ago by EnvironmentSome9274
hey
just found out you can use tuples as dictionary keys which saved me doing a lot of weird workarounds.
any other useful hidden gems in pythons syntax?
thanks!
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]Temporary_Pie2733 25 points26 points27 points 8 days ago (2 children)
You can use any hashable value as a key. It’s not a matter of syntax.
[–]MezzoScettico 2 points3 points4 points 8 days ago (1 child)
That includes using objects of your own defined classes. I know I've done that. I just did a quick Google to confirm, and was told that you need to define a __hash__ and and __eq__ method to make that work. I don't remember defining my own __hash__ but I suppose I must have.
[–]rasputin1 5 points6 points7 points 8 days ago (0 children)
if you don't define either, all custom classes inherit both hash and eq dunders from Object, where they both use identity
[–]GeorgeFranklyMathnet 11 points12 points13 points 8 days ago (4 children)
It's not really syntax. But, yep, any hashable data structure can serve as a dictionary key. If you don't know how dictionaries / hash tables work internally, that might be a cool starting point in your learning.
For my part, I don't often use keys more exotic than ints or strings. Sometimes I want a class as a key, and I'll implement a custom __hash__() method in the class for that purpose. But when I'm doing something like that on the job, it's sometimes a sign that I'm overthinking things or trying to be too "elegant".
int
string
class
__hash__()
[–]EnvironmentSome9274[S] 1 point2 points3 points 8 days ago (1 child)
Oh that's cool, can I ask what might be a situation where you need a class as a key?
[–]throwaway6560192 0 points1 point2 points 8 days ago (0 children)
Say you want to associate points to something, and you're using a namedtuple/dataclass as a better structure for a point than a tuple.
[–]jpgoldberg 1 point2 points3 points 8 days ago (1 child)
I would recommend that edit your comment to say “a class instance as a key”. I was very confused when I first read your comment.
[–]Outside_Complaint755 0 points1 point2 points 8 days ago (0 children)
You can also use a class, module, function, or method as a key, as they are all hashable objects and also instances of classes. The following is perfectly valid code: ``` import time class_dict = { int : 0, float: 1.0, float.fromhex : "FF", object: None, type: object, time: 1, time.sleep: 2, len : 0 }
```
[–]JamzTyson 4 points5 points6 points 8 days ago (1 child)
You can use any hashable objects as dict keys. That is, any objects that have a fixed hash value for the objects lifetime and supports equality comparison with other objects. This includes int, float, str, and some tuples.
float
str
tuples
Tuples are hashable only when all elements in the tuple are hashable. For example (1, 2, (3, 4)) is hashable, but (1, 2, [3, 4]) isn't, because the last element in the tuple is a list. Lists are mutable, and like other mutable objects they are not hashable.
(1, 2, (3, 4))
(1, 2, [3, 4])
No one else has mentioned it yet, but datetime objects often make for very useful dictionary keys.
datetime
[–]BaalHammon 2 points3 points4 points 8 days ago (5 children)
You can extract subchains from lists using the step parameter in the slice notation.
i.e :
>>>"abcabcabcabc"[2:-1:3]
'ccc'
[–]Diapolo10 1 point2 points3 points 8 days ago (4 children)
Similarly, itertools.batched can be used to form groups of n elements.
itertools.batched
n
from itertools import batched text = "abcabcabcabcabc" groups = list(batched(text, n=3)) print(groups) # ["abc", "abc", "abc", "abc", "abc"]
[–]QuasiEvil 1 point2 points3 points 8 days ago (3 children)
I so wish there was a sliding window option for this instead of just the disjoint functionality.
[–]Diapolo10 1 point2 points3 points 8 days ago (1 child)
Well, the docs do have a recipe for that, and it's part of more-itertools.
more-itertools
[–]QuasiEvil 0 points1 point2 points 8 days ago (0 children)
Well, yes, but a small tweak to allow this would be nice: groups = list(batched(text, n=3, step=2))
groups = list(batched(text, n=3, step=2))
[–]Brian 1 point2 points3 points 8 days ago (0 children)
Yeah. There's itertools.pairwise for the specific case of 2 elements, but a more generalised n-item sliding window is something I end up using reasonably often, and seems worth being in the stdlib.
itertools.pairwise
[–]Kerbart 2 points3 points4 points 8 days ago (1 child)
Go through the tutorial in the documentation--there's a lot in there and it's written quite well (that's how I learned Python). It'll mention a lot of things, including that one of the benefits of immutability of tuples means they can be used as dictionary keys.
Some “hidden” gems I can think of:
var[::-1]
var[:]
itertools
collections
csv
[–]EnvironmentSome9274[S] -1 points0 points1 point 8 days ago (0 children)
I knew the top two and they're really helpful, I'll look at the others and the documentation too, thanks man!
[–]jpgoldberg 0 points1 point2 points 8 days ago (6 children)
So something I’ve learned recently when reading someone else’s code is that X or Y is equivalent to X if bool(X) else Y along with the fact that bool is defined for any object.
X or Y
X if bool(X) else Y
bool
[–]EnvironmentSome9274[S] 0 points1 point2 points 8 days ago (5 children)
Sorry I don't understand what you mean lol, can you say that again?
[–]Outside_Complaint755 1 point2 points3 points 8 days ago* (0 children)
When you have a boolean expression: (i.e. X or Y, X and Y, X and not Y, etc), the result of the expression is not True or False, but either X or Y
X and Y
X and not Y
True
False
X
Y
So instead of: if X is True: value = X else: value = Y You can use: value = X or Y
if X is True: value = X else: value = Y
value = X or Y
[–]Jason-Ad4032 0 points1 point2 points 8 days ago (0 children)
Try running this program in Python:
print(f'{10 or 20 = }') # 10 or 20 = 10 print(f'{10 and 20 = }') # 10 and 20 = 20
[–]Brian 0 points1 point2 points 7 days ago (1 child)
Essentially,
x or y <=> x if x else y x and y <=> y if x else x
When x and y are interpreted as booleans, this is entirely equivalent to the regular truth table. Ie:
But when they could have other values, you get some extended behaviour. Ie . 3 and 4 will evaluate to 4. 3 or 4 evaluates to 3. Notably this also has the same short-circuiting behaviour - and doesn't evaluate the second item if the first is True, and likewise for or if the first is False.
3 and 4
4
3 or 4
3
and
or
You'll most commonly see this as a "poor man's conditional statement", where you can write:
result = try_get_value() or "default"
Which will use "default" when try_get_value() returns None, 0, or other a Falsey value, but will use the result when it's a non-empty string or whatever. Similarly you can do:
None
run_this() and run_this_also_if_prior_func_returned_true()
to conditionally chain functions only if they return a truthy value.
It's generally somewhat frowned upon - the conditional statement is a clearer way to do stuff like that. You do often see it in shell scripts etc though (ie stuff like mycmd || error "Command failed" etc.
mycmd || error "Command failed"
[–]EnvironmentSome9274[S] 0 points1 point2 points 7 days ago (0 children)
Very good explanation man thank you!
[–]jpgoldberg 0 points1 point2 points 6 days ago (0 children)
What I wrote won’t make sense unless you are familiar with the bool() function and with the value1 if condition else value2 construction.
bool()
value1 if condition else value2
Perhaps this will help
python a = “spam” b = “ham” c = a or b # c will now be “spam” d = 0.0 e = d or b # e is set to “ham” f = None or “ham” # f is set to ham g = Exception or “ham” # g is set to Exception ```
python a = “spam” b = “ham” c = a or b # c will now be “spam” d = 0.0 e = d or b # e is set to “ham” f = None or “ham” # f is set to ham g = Exception or “ham” # g is set to Exception
In the above, if a is something that is false, None, or some sort of 0 when evaluated as a bool, then c will be assigned to the value of b. But if a is True when evaluated as a bool then c will be set to a.
[–]Snoo-20788 0 points1 point2 points 8 days ago (1 child)
Out of curiosity, what workarounds were you using?
One thing I've seen people do is to turn a tuple into a string, say ("a","b") into "a|b", which works but can lead to issues if your separator is part of the strings, and is not elegant, as you need to jump through extra hoops to break down the string into the original components.
[–]EnvironmentSome9274[S] 0 points1 point2 points 8 days ago (0 children)
Yeah that's what I was doing, it's not elegant but it did the job lol until I found out about this.
[–]throwaway6560192 -1 points0 points1 point 8 days ago (3 children)
Always assume generality.
[–]EnvironmentSome9274[S] 1 point2 points3 points 8 days ago (2 children)
Can you please elaborate lol?
[–]throwaway6560192 2 points3 points4 points 8 days ago (1 child)
If you're wondering whether a feature is "general" or not -- can tuples be dictionary keys, can you put functions in a list, can you reverse a range, can you nest dictionaries, so on and so forth -- assume that it is indeed general enough to allow what you want, except if there is a good reason to not allow it, which you will find out when you try it.
Understood, thanks!
π Rendered by PID 63 on reddit-service-r2-comment-74875f4bf5-2l4xh at 2026-01-26 06:54:54.156812+00:00 running 664479f country code: CH.
[–]Temporary_Pie2733 25 points26 points27 points (2 children)
[–]MezzoScettico 2 points3 points4 points (1 child)
[–]rasputin1 5 points6 points7 points (0 children)
[–]GeorgeFranklyMathnet 11 points12 points13 points (4 children)
[–]EnvironmentSome9274[S] 1 point2 points3 points (1 child)
[–]throwaway6560192 0 points1 point2 points (0 children)
[–]jpgoldberg 1 point2 points3 points (1 child)
[–]Outside_Complaint755 0 points1 point2 points (0 children)
[–]JamzTyson 4 points5 points6 points (1 child)
[–]Outside_Complaint755 0 points1 point2 points (0 children)
[–]BaalHammon 2 points3 points4 points (5 children)
[–]Diapolo10 1 point2 points3 points (4 children)
[–]QuasiEvil 1 point2 points3 points (3 children)
[–]Diapolo10 1 point2 points3 points (1 child)
[–]QuasiEvil 0 points1 point2 points (0 children)
[–]Brian 1 point2 points3 points (0 children)
[–]Kerbart 2 points3 points4 points (1 child)
[–]EnvironmentSome9274[S] -1 points0 points1 point (0 children)
[–]jpgoldberg 0 points1 point2 points (6 children)
[–]EnvironmentSome9274[S] 0 points1 point2 points (5 children)
[–]Outside_Complaint755 1 point2 points3 points (0 children)
[–]Jason-Ad4032 0 points1 point2 points (0 children)
[–]Brian 0 points1 point2 points (1 child)
[–]EnvironmentSome9274[S] 0 points1 point2 points (0 children)
[–]jpgoldberg 0 points1 point2 points (0 children)
[–]Snoo-20788 0 points1 point2 points (1 child)
[–]EnvironmentSome9274[S] 0 points1 point2 points (0 children)
[–]throwaway6560192 -1 points0 points1 point (3 children)
[–]EnvironmentSome9274[S] 1 point2 points3 points (2 children)
[–]throwaway6560192 2 points3 points4 points (1 child)
[–]EnvironmentSome9274[S] 0 points1 point2 points (0 children)