4 ms·
That's much better, but like the original implementation it's still missing the -n flag for sort, which extracts numbers at the beginning of lines and sorts the
by BoppreH 4y ago
That's much better, but like the original implementation it's still missing the -n flag for sort, which extracts numbers at the beginning of lines and sorts them numerically instead of lexicographically.
- falcor84 4y agoOh, I always thought it only works on numbers, and am very pleasantly surprised to learn it works on numeric prefixes, thank you! EDIT: After playing around with the python approach, I arrived at this, which is definitely more verbose, but arguably, more maintainable: import re NUMERIC_PREFIX_RE = re.compile(r"^(\d+.?\d*)") def numeric_descending(line): if m := NUMERIC_PREFIX_RE.match(line): return -float(m.group()) return float("inf") matches = {l for l in open("beef.txt") if "lasagna" in l} print(*sorted(matches, key=numeric_descending), sep="")
- pama 4y agoNot sure it is more maintainable than a shell solution. Look at this in two years from now thinking there might be a bug somewhere in there (say you want to include negatives and scientific notation). In the shell, a quick inspection suffices. In this case you have to deal with regular expressions within Python, their own little special language… and it may not spark joy.
- falcor84 4y agoWell, it seems you nerd-sniped me a bit, so here's a new version which deals well with scientific notation (negatives were already supported) and is actually simpler, using a split and "it's better to ask for forgiveness..." instead of the regex: def numeric_descending(line): possible_number = line.split()[0] try: return (-float(possible_number), line) except ValueError: return (float("inf"), line) matches = {l for l in open("beef.txt") if "lasagna" in l} print(*sorted(matches, key=numeric_descending), sep="")
- pama 4y agoThanks, and apologies---I didn't mean to come off as negative. Yes, this code is cleaner and certainly maintainable a couple years down the road. It will work in a slightly different way than the shell script (the lack of space in "10oz" of lasagna vs "2.0e1 oz" of lasagna), however I'd consider this a feature rather than a bug, as it could help identify bad formatting in the input data. I've learned from experience that it is hard to replace certain simple space and memory efficient programs that have been tuned over the course of 40 or more years. If one wanted to print only a single instance of a line in a file, then python's set construct in your snippet is certainly sparking more joy compared to the awk equivalent of printing only the first instance of a line in a file: awk '!x[$0] {print; x[$0]=1}' Tuning python to use ordered dicts to keep the line order looks a little less pleasant (and might appear confusing to an uninitiated), but would still be rather neat. There are many instance of day-to-day data inspection tasks where bash, sort, shuf, sed, grep (or rg), and awk will solve a problem near optimally out of the box and can combine nicely in modest memory machines to tackle large data, when some python native code (or poorly designed python library) might accidentally cause a performance mess. Interactive shells are an awesome superpower that is hopefully going to stay with us for a while. I'd have personally been happy if some type of Lisp REPL had won over the shell fights, but we don't live in that world, so python + posix tools via a shell will have to work in practice for most people.