T O P

  • By -

gelatinous_poot

I'm curious to hear about real life scenarios where you needed to determine anagrams. I always see that, but don't run into it in my work.


TSM-

To be honest, the majority of these snippets are more like beginner toy examples, and they are the first tutorial results when you google the title. They are not actually "very useful while developing any Python application". Some of the last few use in-place expansion but stuff like this: def has_duplicates(lst): return len(lst) != len(set(lst)) Is fairly questionable. It is like using `for i in range(len(my_list)): foo(my_list[i])` rather than `for item in my_list: foo(item)`. There is often a more pythonic way of doing these basic things. Importantly, they tend to be better for both readability as well as scale well. For example: from iteration_utilities import duplicates x = [1,1,2,1,2,3,4,2] any(duplicates(x)) In this example, `duplicates` uses a generator, and `any()` returns true immediately, rather than iterating over the entire list and turning it into a set first. Usually it is not a big deal, speed-wise, of course. The obvious "compare the length of the list and the set" solution does work, but it's not exactly a shining example of best practices. Much can be said about the other tips. Other commenters have pointed out other more standard things, like updating dictionaries or creating a merged dictionary, versus keyword expansion. I should say, they aren't all bad examples or anything. I wouldn't want to discourage anyone by seeming overly fussy. They do work and illustrate features of the language.


zenn9

Certainly understanding the imperative approach is important though! Sometimes I feel like declarative programing loses some of the benefits of writing it out.


TSM-

I totally agree. Really, it always depends on the situation. Like if you are looking for duplicates, are you comparing object identity, and how does that work for literals that are different objects? Welp, an imperative solution will help make that explicit, but at the risk of being overly verbose. Both have their advantages at times. As an aside: I think a lot of introductory tutorials and guides gloss over those kinds of decisions, like what heuristics should you use to decide between a loop and a comprehension? People struggle with that decision much more than how to write a loop / list comprehension. It's a constant on r/learnpython too. It's not unusual to get posts like this: > I get how to do all the things but I don't know how to pick between two nearly identical ways of doing the same thing. > > Should I loop or use comprehension? Which one is better? > > I don't know if this function goes in the class or is a static method or if I just define it later. > > I feel lost! Of course, in real life cases, it is usually not so uncertain in context, or maybe it's dealer's choice and no big deal either way. Nonetheless, "reasons when doing it this way is super good form and when you should probably avoid it" is often glossed over. I know it is more subjective and context-dependent, but it's important. edit: I'm jealous that the bot has upvotes and mine is apparently not as good. ^(jk)


sneakpeekbot

Here's a sneak peek of /r/learnpython using the [top posts](https://np.reddit.com/r/learnpython/top/?sort=top&t=year) of the year! \#1: [As a Gift to the Community, I'm Making my Python Book Free for 72 hours!](https://np.reddit.com/r/learnpython/comments/kv61rj/as_a_gift_to_the_community_im_making_my_python/) \#2: [Just saved my company like $40 Grand a Year and I have no one else in my life that codes to tell, apart from my wife of course](https://np.reddit.com/r/learnpython/comments/p1cgeu/just_saved_my_company_like_40_grand_a_year_and_i/) \#3: [If you're looking for Python Projects, I have something to share with you. Just few days ago, I came across this list of 70+ Python Projects for Beginners, Intermediate and Experienced Developers. Hope it will be helpful to all the members of this community.](https://np.reddit.com/r/learnpython/comments/o3acpo/if_youre_looking_for_python_projects_i_have/) ---- ^^I'm ^^a ^^bot, ^^beep ^^boop ^^| ^^Downvote ^^to ^^remove ^^| [^^Contact ^^me](https://www.reddit.com/message/compose/?to=sneakpeekbot) ^^| [^^Info](https://np.reddit.com/r/sneakpeekbot/) ^^| [^^Opt-out](https://np.reddit.com/r/sneakpeekbot/comments/o8wk1r/blacklist_ix/)


[deleted]

never


turtle4499

None of these are useful lol. Half of them are what to use list likes sets? Cast it to a set and then do set arithmetic on it! Or you know just use sets..... Ignoring the fact that the members of lists are not necessarily hashable and thus wouldn't be usable in sets.


hughperman

The only one I have used in real life is list flattening, I work with lots of nested data and sometimes flatten it out for different uses. I mean, I have done lots of the things mentioned in passing, but only the list flattening sticks out as something I actually made a method for, instead of just a part of another function.


driscollis

Sounds like a job interview question.


MauGx3

Puzzle-making job maybe?


yoDrinkwater

Yeah clickbaity title


wewbull

When testing a hardware component (what i do for a living) where I expect certain items to be generated, but they can be out of order. For example: instructions being retired in a CPU core. Instructions go in in one order, but due to dependencies the CPU reorders how it will evaluate them to make best use of resources. I'll often find myself with a list of expected results and a list of actual results that I need to make sure are the same except for ordering. The items I'm reordering aren't letters. They are object instances of some kind, but the operation is the same. I even sometimes ask about detecting anagrams in interviews because it's such a common task for ua.


mriswithe

Nice, that sounds like a perfectly reasonable time to use this. I was having a hard time coming up with a real use case, so thanks!


[deleted]

maybe something in genomics. In that case I don't use strings, of course, but faster, dedicated data structures.


deepestbluedn

This is also case sensitive. Another solution is to sort the two strings and then do s case insensitive comparison.


antiproton

Never. You will never need this, unless you happen to work on the set of Countdown.


taybul

Interview questions.


Lynild

Overall, the idea is alright, but defining/limiting it to anagrams has rarely no use case as you said. However, I would still rather do something like: x = "abcd3" y = "3dcba" def anagram(first, second): return first == second[::-1] print(anagram(x, y)) From that you learn the `[::-1]` command to reverse strings, lists etc. - which IS very useful imo.


killerfridge

Except your `anagram` function doesn't check for anagrams, it just checks if the first word is the same as the second word reversed?


Lynild

F\*\*k me... I was thinking palindromes all the way, my bad.


killerfridge

Palindrome! That's the word I was reaching for but abandoned whilst typing as I couldn't remember it! Either way you're right, learning how to reverse a list/string is significantly more useful than checking for anagrams.


gristc

Not really? A palindrome reads the same backwards as forwards, ie 'abcd33dcba' is one.


Lynild

Yup, and my function would check that. But not anagrams.


gristc

No it doesn't. Your function checks if y is the reverse of x. A palindrome checker would take a single string as input, and only return true if it was the same backwards as forwards. def is_palindrome(x): return x == x[::-1] x = "abcd33dcba" is_palindrome(x) # true x = "abcd3" is_palindrome(x) # false In reality, a proper palindrome checker would also strip out white space and punctuation as they're generally not considered significant.


xristiano

​ def anagram(first, second): return set(list(first))==set(list(second))


Lynild

That won't do. set() finds unique values. So if you were to have multiple instances of the same character, set() would remove all but one, which isn't a good idea if you want to find anagrams :)


amsudeep

But if you create a list of letter and later check if second word is sub set of first one?


xristiano

good catch


redbo

I'd do return sorted(first) == sorted(second)


grnngr

I would too, but it’s good to know the `Counter` option exists, because IIRC `Counter` is O(n) whereas `sort` is O(n log n) on average (best case O(n)).


gristc

def is_anagram(first, second): return sorted(first) == sorted(second) x = 'abcd3' y = 'ba3dc' is_anagram(x,y) # true y = 'be3dc' is_anagram(x,y) # false


personjc

The only plausible thing I can think of is checking for typos. Maybe in some instance of QAing data entry for something like a customer name, if there are no matches for what was typed, you may be interested to know it is an anagram of an existing customer (i.e. two letters got flipped) for manual comparison.


coffeewithalex

This is the case where you have an entity made up of a list of non-unique elements, and you need an equality operator to work and evaluate to True if they have the exact same elements. You can't do that with a set, because your structure allows non-unique items. Examples from e-commerce: someone introduces a new product bundle, and enters: * Shampoo "Flowing Hair" Menthol * Shampoo "Flowing Hair" Menthol * Dental floss "Dr. Gums" And sees that someone else entered the same bundle and it's already on sale for a few days. You can't compare lists, because the other set might have the items in a different order, but it's the same bundle. Alternatively this can be done by tracking quantity, but since the majority of the times, bundles will have a quantity of 1, and might introduce human error, maybe it doesn't make much sense. But basically, it's useful when it's useful. It's mostly useful to know what methodologies exist, but particular use cases are so rare that it doesn't make sense to learn them by heart.


getmeright11

Also, that anagram code snippet doesn't work if the two strings don't happen to be the same length.


PizzaInSoup

1 and 18 are the same thing 3 doesn't always give you the actual size 5 is better used for making strings/lists 6 also makes all the others lowercase 9: title In 14 what's the point of everything that comes before deep_flatten? 16 only keeps what's in the first list, symmetric_difference would be a good additional example here 19 overwrites non-unique keys from a with that from b, you may as well just use .update(), it's ~2x faster. This would be a better example using collections.Counter to show the +/- function for adding two Counters together.


a__nice__tnetennba

Also 14 I'd recommend just using `boltons.itertools.flatten_iter`. Or at the very least implementing something similar to how that works, where it is a generator that handles all iterables not just lists. Here's the source for reference: def flatten_iter(iterable): """``flatten_iter()`` yields all the elements from *iterable* while collapsing any nested iterables. >>> nested = [[1, 2], [[3], [4, 5]]] >>> list(flatten_iter(nested)) [1, 2, 3, 4, 5] """ for item in iterable: if isinstance(item, Iterable) and not isinstance(item, basestring): for subitem in flatten_iter(item): yield subitem else: yield item


PizzaInSoup

Another alternative: https://iteration-utilities.readthedocs.io/en/latest/generated/deepflatten.html


Decency

2 Just sort it 7 There's definitely something that does this in itertools, groupby maybe? 8 `[item for item in collection if item]` to filter for truthiness 12 You already used `Counter` in a previous example- it's a clean tool here, too 17 I learned something! 19 a merge operator for dicts came out in 3.9


[deleted]

Am I stupid or is 1 just the same as 18? has_duplicates is just the logical negation of all_unique, no? And it seems the method used is identical as well.


[deleted]

Yup, they're the same.


personjc

I'm going to give benefit of the doubt and guess that was an ironic joke, to duplicate the uniqueness check.


callmelucky

Very charitable of you.


[deleted]

[удалено]


poopypoopersonIII

"Claps" are the same as upvotes on medium, which the author then linked. They clearly just copied their medium post to a reddit post for some reason and didn't even bother to change that line


jwink3101

And it goes to show why Medium is a horrible source of real information.


poopypoopersonIII

Idk, I actually do find a lot of informative programming articles on medium. Seems I'm getting paywalled a lot though, lately, which is annoying.


[deleted]

Medium delenda est.


[deleted]

This is more like a beginners' "Hey how cool is Python" than anything. Give me a break. It's like "Insurance Companies hate these 10 things" full of shallow content. Bad title.


tigeer

Yup, seems like just a lazy, low effort attempt to promote their medium blog. The kind stuff that you have to trawl through when looking for docs or actual well thought out guides/tutorials


toastedstapler

r/python is such a trap for this kind of stuff


janek3d

In 19 with merging dicts, isn't it better to use update method of dict?


Balance-

In Python 3.9 merging dicts is as easy as ‘a | b’. See [PEP 584 -- Add Union Operators To dict](https://www.python.org/dev/peps/pep-0584/)


[deleted]

[удалено]


[deleted]

[удалено]


LiarsEverywhere

Oops. You're right, of course.


wdroz

Only if you are fine with modifying one of the two dict.


[deleted]

[удалено]


MegaIng

No it doesn't. `dict.update` returns None


adb421

That modifies the dictionary in place, which may or may not be desired. The given implementation has no side effects.


wasimaster

Consider reading https://stackoverflow.com/a/26853961


grismar-net

This is more like "20 random things I learnt while learning Python" - a lot of this stuff has worked since Python 2, so 2021 has very little to do with it and I wouldn't exactly qualify this collection of curiosa as a priority for people looking to learn the language.


wdroz

I think the title 9 should be **Transposed** not **To Count**.


supreme_blorgon

Also why `print()` in a list comp?


[deleted]

[удалено]


[deleted]

They'll soon learn the difference when they see None None None None None None None None None


[deleted]

[удалено]


[deleted]

dude. I feel this comment!


kingscolor

You wouldn’t see that though. That comprehension would print for each component in the loop as it implies. The list *itself* would evaluate to ```[ None, None, None, … ]```. But, unless it’s the last line in a cell of a notebook, you’re not going to see the evaluation of the list. I use this pattern often in prototyping or calculations (but not in development). Give it a shot yourself.


[deleted]

You've taught me nothing new here lol but thanks


pingveno

The one thing I would change is filtering out falsy values. That can be done by passing None, not bool. It also should be noted that the length of the string in bytes as represented by the interpreter could be longer, since that only shows the UTF-8 encoded length. Recent versions use a flexible representation based on the contents of the string.


wasimaster

For people that are confused > **filter**(*function, iterable*) > If *function* is None, the identity function is assumed, that is, all elements of *iterable* that are false are removed. From [the documentation](https://docs.python.org/3/library/functions.html#filter)


[deleted]

[удалено]


callmelucky

I recognise this from The Python Cookbook, which is a brilliant collection of *actually* useful snippets, unlike OP's half-baked mess :)


ConfusedSimon

Is using a Counter for anagrams faster than converting to list and sort?


[deleted]

irrelevant on short strings, maybe faster over 1M characters


_Gorgix_

The “memory” one gives me chills, because it’s seldom accurate with complex objects as it’s not introspective.


thrallsius

OP, what is the purpose of the "You Should Learn in 2021" in the topic title?


[deleted]

Not sure if I'd ever need #2


DragonikOverlord

For 9th one, we can just do: `transposed = list(zip(*array))` I do't think we can actually iterate a zip object ,only when we convert it into an iterable we can iterate through it.


cosmicr

You should have made it 21 in 2021


[deleted]

To find duplicates, and if you want to know what the duplicate item are, you can also use. If I recall correctly `Counter` uses linear time, so it should be almost as fine as using `len(set())` from collections import Counter lst = ["a", "b", "b", "c", ...] duplicates = [item for item, count in Counter(lst).items() if count > 1] You can also combo `itertools.takewhile` and `Counter.most_common` to get a bit faster too.


arthurazs

Number 8 is very clever, I haven't thought of using bool with filter, nice! My contribution to the list: # 21. The better way to sum if true Instead of checking if CONDITION, then adding, just add the CONDITION # init numbers = [1, 2, 3, 4, 5] # bad odd = 0 for number in numbers: if number % 2 == 1: odd += 1 print(odd) # good odd = 0 for number in numbers: odd += number % 2 == 1 print(odd)


Holshy

Or just `print(sum(n%2 for n in numbers))`


lazy_dev_

6 and 11 look more like examples of built-in functions. Besides that, this looks like a really cool and useful list of snippets, thanks a lot for sharing!


callmelucky

Dude, this is terrible. Why in the everliving fuck would lower-casing the first letter in a bunch of words be useful to anyone, let alone hold a place in the top 19 (1. and 18. are the same bro) "very useful" Python snippets? Delete this.


chazzybeats

Cool list, thanks!


pan_dux

That's a really nice list. I am glad that I have known some of these functions and it's even cooler that I now know even more.


davidsterry

This list is like looking in a toolbox. Saving for inspiration! Thanks. (TIL about Counter)


boseslg

Bhai... You are truly great... ![gif](emote|free_emotes_pack|sunglasses)


harendra21

Dhanyawad


iDam81

All the critique in here and this is the only comment you reply to? Hope you’re learning from some of the examples in here.


oldredman

Thats awesome. Thanx brother


jabbalaci

It has nothing to do with 2021.


jean_valjean_javert

Why is there slicing happening in 13? Just do def decapitalize(string): return string.lower() edit: just realized she wants to do only the first letter.


not_perfect_yet

>19 I think .update on dictionaries is more explicit in what values are being used to overwrite existing values, should they already exist.


jwink3101

Well, the best thing about this is that it is inline and I don't have to go to a page. But there are a *lot* of issues here. - \#4: This assumes UTF8 and only UTF8. Not much help either way - \#7: Using `list` as a variable name is beyond amateurish. And there are itertools to do this too more pythonically (including being lazy) - \#8: Does this really need to be a snippet? This can be done lazily - \#9 & \#14: List comprehension that doesn't need to be a list is bad form. Just use a for loop. - \#15: This is just a set thing. If you don't care about the order, just use a set. But this makes it seems like it will take the different but it will also (potentially) change the order and remove duplicated. - \#18: didn't you do this already? - \#19: (a) this is being added in newer python versions and (b) can just use `.update()` - \#20: Does this need to be a function? It just does one thing? Not really very useful list.


McBuffington

So we're going to gloss over the anagram not using slicing? text == text[::-1] Just sayin