Code: Select all
def checkSorted(_list, comparison = operator.le):
return all([comparison(*x) for x in [(_list[i], _list[i + 1]) for i in range(len(_list) - 1)]])
I invite other examples of Python awesomeness.
Moderators: phlip, Moderators General, Prelates
Code: Select all
def checkSorted(_list, comparison = operator.le):
return all([comparison(*x) for x in [(_list[i], _list[i + 1]) for i in range(len(_list) - 1)]])
Code: Select all
def checkSorted(_list, comparison = operator.le):
return all(comparison(*x) for x in ((_list[i], _list[i + 1]) for i in xrange(len(_list) - 1)))
Code: Select all
def checksorted(alist, comparison=operator.le):
return all(comparison(alist[i], alist[i + 1]) for i in xrange(len(alist) - 1))
ameretrifle wrote:Magic space feudalism is therefore a viable idea.
Code: Select all
class Marker:
pass
def check_sorted(seq, comp=operator.le):
marker = first = Marker()
for second in seq:
if (first is not marker) and (not comp(first, second)):
return False
first = second
return True
Code: Select all
def iter_tail(seq):
it = iter(seq)
try:
it.next()
return it
except StopIteration:
return iter(seq)
def check_sorted(seq, comp=operator.le):
return all(comp(fst, snd) for (fst, snd) in itertools.izip(seq, iter_tail(seq)))
Code: Select all
class PairedIterator:
def __init__(self, seq):
self._iter = iter(seq)
try:
self._prev = self._iter.next()
except StopIteration:
self._prev = None
def __iter__(self):
return self
def next(self):
old_prev = self._prev
self._prev = self._iter.next()
return (old_prev, self._prev)
def check_sorted(seq, comp=operator.le):
return all(comp(fst, snd) for (fst, snd) in PairedIterator(seq))
EvanED wrote:Code: Select all
class Marker:
pass
...
marker = first = Marker()
It's really not that bad. Creating an internal type and then an instance of that type that is difficult or impossible for users to access, then using that instance as a sentinel value to distinguish from any user-provided value like None, is quite idiomatic, though usually I've seen it applied to default argument values.xGeovanni wrote:EvanED wrote:Code: Select all
class Marker:
pass
...
marker = first = Marker()
You can't convince me that this is anything but immensely icky and weird.
Code: Select all
def check_sorted(seq, comp=operator.le):
is_first_iteration = True
for second in seq:
if (not is_first_iteration) and (not comp(first, second)):
return False
is_first_iteration = False
first = second
return True
Code: Select all
def primes():
"""Prime number generator using Sieve of Eratosthenes."""
# Instead of crossing off every multiple of a prime up to some bound, we just
# cross off the next uncrossed multiple of a prime. Crossed off numbers are
# stored in lazy_sieve, together with the factor, which we can use to figure
# out the next number to cross off. One new (int: int) pair is stored in each
# iteration, so when this function yields n, we are using O(n*log(n)) memory.
lazy_sieve = {}
next_candidate = 2
while True:
if next_candidate not in lazy_sieve:
# next_candidate is prime. Yield it and cross off its square.
yield next_candidate
lazy_sieve[next_candidate * next_candidate] = next_candidate
else:
# next_candidate is composite. Cross off the next number.
factor = lazy_sieve[next_candidate]
next_composite = next_candidate + factor
while next_composite in lazy_sieve:
next_composite += factor
lazy_sieve[next_composite] = factor
del lazy_sieve[next_candidate]
next_candidate += 1
Code: Select all
def primes(n):
''' Return a boolean list of all primes < n '''
s = [False]*2 + [True]*(n-2)
for i in xrange(2, int(n**0.5) + 1):
if s[i]:
s[i*i : n : i] = [False] * (1 + (n - 1)/i - i)
return s
#test
print [i for i,v in enumerate(primes(100))if v]
Code: Select all
def checksorted(seq, comp=operator.le):
left, right = itertools.tee(seq, 2)
return all(comp(a, b) for (a, b) in itertools.izip(left, itertools.islice(right, 1, None)))
Code: Select all
def checksorted(seq, comp=operator.le):
xs = list(seq)
return all(comp(a, b) for (a, b) in zip(xs, xs[1:]))
Code: Select all
enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵╰(ಠ_ಠ ⚠) {exit((int)⚠);}
To generate all primes less than 100, skepsci's algorithm took 0.061000 milliseconds while PM 2Ring's algorithm took 0.025000 milliseconds.
To generate all primes less than 1000, skepsci's algorithm took 0.640000 milliseconds while PM 2Ring's algorithm took 0.037000 milliseconds.
To generate all primes less than 10000, skepsci's algorithm took 6.603000 milliseconds while PM 2Ring's algorithm took 0.267000 milliseconds.
To generate all primes less than 100000, skepsci's algorithm took 70.966000 milliseconds while PM 2Ring's algorithm took 3.653000 milliseconds.
To generate all primes less than 33554432, skepsci's algorithm took 33833.623000 milliseconds while PM 2Ring's algorithm took 2721.861000 milliseconds.
Code: Select all
import time
def compare_times(n):
t_0 = time.clock()
for p in primes():
if p > n: break
t_1 = time.clock()
primes2(n)
t_2 = time.clock()
return (n, t_1 - t_0, t_2 - t_1)
def print_times(n, t_1, t_2):
print ("To generate all primes less than %d, skepsci's algorithm took %f "
"milliseconds while PM 2Ring's algorithm took %f milliseconds." %
(n, 1000 * t_1, 1000 * t_2))
def print_ratio(n, t_1, t_2):
print ("To generate all primes less than %d, PM 2Ring's algorithm was faster "
"by a factor of %f." % (n, t_1 / t_2))
phlip wrote:For the "check_sorted" example, EvanED's examples can be cleaned up a fair bit with more use of itertools...That said, if the lists weren't too long, and I wasn't too worried about performance, I'd probably for readability write it as:Code: Select all
def checksorted(seq, comp=operator.le):
left, right = itertools.tee(seq, 2)
return all(comp(a, b) for (a, b) in itertools.izip(left, itertools.islice(right, 1, None)))Code: Select all
def checksorted(seq, comp=operator.le):
xs = list(seq)
return all(comp(a, b) for (a, b) in zip(xs, xs[1:]))
skeptical scientist wrote:Yours is significantly faster:
[...]
The advantage of mine is really that it's unbounded. Yours is much faster if you want all primes less than a specific bound which you know ahead of time, whereas the purpose of mine is to be an unbounded generator. I'm not sure how much of the speed difference is because when your algorithm computes primes(n), it only ever bothers considering numbers less than n, while by the time my algorithm has finished generating all primes below n, it's already started marking composites larger than n, because it needs to store enough state to keep going.
Code: Select all
def potential_primes():
''' Make a generator for 2, 3, 5, & thence all numbers coprime to 30 '''
s = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29)
for i in s:
yield i
s = (1,) + s[3:]
j = 30
while True:
for i in s:
yield j + i
j += 30
Code: Select all
def potential_primesA():
''' Make a generator for 2, 3, 5 & thence all numbers coprime to 6 '''
for i in (2, 3, 5):
yield i
j = 6
while True:
yield j + 1
yield j + 5
j += 6
PM 2Ring wrote:I really ought to familiarise myself with itertools...
Code: Select all
enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵╰(ಠ_ಠ ⚠) {exit((int)⚠);}
Code: Select all
enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵╰(ಠ_ಠ ⚠) {exit((int)⚠);}
Breakfast wrote:Qaanol, please feel free to correct me or shout at me if I'm wrong but I think that his point was just that. It's just like every other language. The title of the thread is making a ridiculous claim based on a piece of code that can be reproduced more succinctly in other languages or implemented in a multitude of ways in Python.
That is groovy, and I do like them.PM 2Ring wrote:phlip wrote:For the "check_sorted" example, EvanED's examples can be cleaned up a fair bit with more use of itertools...[code]def checksorted(seq, comp=operator.le):
...
Groovy, phlip!
Qaanol wrote:So, as someone unfamiliar with Python, here is what I have gleaned from this thread:
In Python there are numerous ways to accomplish simple tasks, using many different functions and classes that require knowing lots of different keywords and syntax.
It is not always obvious, even to people who are familiar with the language, what all the different approaches to a problem are, not even all the simple approaches.
Nor is it obvious which methods are fastest or use the least memory, and determining those things requires carrying out many tests of each of the large number of possible implementations, using a wide range of input values.
Qaanol wrote:Breakfast wrote:Qaanol, please feel free to correct me or shout at me if I'm wrong but I think that his point was just that. It's just like every other language. The title of the thread is making a ridiculous claim based on a piece of code that can be reproduced more succinctly in other languages or implemented in a multitude of ways in Python.
Yeah, when I saw the thread title I was expecting examples of elegant solutions for problems that would be more complicated or difficult to solve in other languages, thus providing reasons for a person like myself to learn this language. That did not happen.
Indeed, right now it's almost the opposite.Hopefully, this thread will evolve to give examples of elegant solutions for problems that illustrate the power of Python... or at least the tendency of Python syntax to look cleaner than that of most other languages.
All Shadow priest spells that deal Fire damage now appear green.
Big freaky cereal boxes of death.
Code: Select all
a, b = b, a
Code: Select all
def fibo():
a = b = 1
while True:
yield a
a, b = b, a + b
Since you're using "is" comparison, you can just use object() for this. There's no need for the class to be hidden from users, since they would have to somehow pass the actual instance you're using a sentinel to screw things up.EvanED wrote:It's really not that bad. Creating an internal type and then an instance of that type that is difficult or impossible for users to access, then using that instance as a sentinel value to distinguish from any user-provided value like None, is quite idiomatic, though usually I've seen it applied to default argument values.
PM 2Ring wrote:Code: Select all
def primes(n):
''' Return a boolean list of all primes < n '''
s = [False]*2 + [True]*(n-2)
for i in xrange(2, int(n**0.5) + 1):
if s[i]:
s[i*i : n : i] = [False] * (1 + (n - 1)/i - i)
return s
#test
print [i for i,v in enumerate(primes(100))if v]
Code: Select all
File "primes.py", line 10
print [i for i,v in enumerate(primes(100))if v]
^
SyntaxError: invalid syntax
Code: Select all
Traceback (most recent call last):
File "primes.py", line 10, in <module>
print ([i for i,v in enumerate(primes(100))if v])
File "primes.py", line 4, in primes
for i in xrange(2, int(n**0.5) + 1):
NameError: global name 'xrange' is not defined
Code: Select all
Traceback (most recent call last):
File "primes.py", line 10, in <module>
print ([i for i,v in enumerate(primes(100))if v])
File "primes.py", line 6, in primes
s[i*i : n : i] = [False] * (1 + (n - 1)/i - i)
TypeError: can't multiply sequence by non-int of type 'float'
What version of Python? Works fine for me with both 2.7 and 3.3:Diadem wrote:Ok so how do you even run the first program? It gives an error about opeator.le not existing, even if I import operator.
Code: Select all
Python 2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import operator
>>> def checkSorted(_list, comparison = operator.le):
... return all([comparison(*x) for x in [(_list[i], _list[i + 1]) for i in range(len(_list) - 1)]])
...
>>> checkSorted([1,2,3])
True
>>> checkSorted([1,2,3,1])
False
Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:06:53) [MSC v.1600 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import operator
>>> def checkSorted(_list, comparison = operator.le):
... return all([comparison(*x) for x in [(_list[i], _list[i + 1]) for i in range(len(_list) - 1)]])
...
>>> checkSorted([1,2,3])
True
>>> checkSorted([1,2,3,1])
False
It needs an int(...) around 1 + (n - 1)/i - i, because division results in a floating point instead of integer in Python 3.Ok I have no idea what that means, and in the time it will take me to figure that out, I can probably write this algorithm in c++ as well.
EvanED wrote:It needs an int(...) around 1 + (n - 1)/i - i, because division results in a floating point instead of integer in Python 3.
Code: Select all
enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵╰(ಠ_ಠ ⚠) {exit((int)⚠);}
Code: Select all
enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵╰(ಠ_ಠ ⚠) {exit((int)⚠);}
phlip wrote:Just a note that if this thread moves from being an excuse to share neat Python snippets to being an actual discussion of "the best programming language in the world", then it's getting moved to RW. Not saying you can't go down that road... but just putting that out there.
phlip wrote:EvanED wrote:It needs an int(...) around 1 + (n - 1)/i - i, because division results in a floating point instead of integer in Python 3.
Or just change the / to // to get an integer division (really should be using that explicitly, even in Python 2, when you need integer division).
Code: Select all
template <class fwditer>
bool is_sorted (fwditer first, fwditer last) {
return adjacent_find(first, last, greater<decltype(*first)>()) == last;
}
Code: Select all
import operator
def check_sorted(itbl, op=operator.le):
iterator = iter(itbl)
x1 = next(it)
for x2 in iterator:
if not op(x1,x2): return False
x1 = x2
return True
If I need a sentinel/special value, I usually just useCode: Select all
class Marker:
pass
def check_sorted(seq, comp=operator.le):
marker = first = Marker()
# <snip>
Code: Select all
marker = object()
troyp wrote:(I'd use skeptical's function for lists)
Code: Select all
def window(it, k):
# unoptimized - probably no good for large k (deque for large k? all k?)
it = iter(it)
items = []
for i in range(k):
items.append(next(it))
while True:
yield tuple(items)
items = items[1:]
items.append(next(it))
skeptical scientist wrote:I don't think I wrote one. Are you thinking of one of EvanED's posts?
I like how this never actually raises StopIteration, just waits for the underlying iterator to raise it.
Imo this thread would be more interesting if people would stop talking about how to check whether a list is sorted, and instead show off some other cool python features with interesting applications.
Code: Select all
@decorator
def foo(args):
code
Code: Select all
foo = decorator(
(lambda args:
code))
Code: Select all
class Switch(object):
def __init__(self, expr):
self.expr = expr
def __iter__(self):
return iter([Switch.Case(self.expr)])
class Case(object):
def __init__(self, expr):
self.expr = expr
self.result = None
def __call__(self, val):
if self.expr == val:
return Switch.CaseHandler(self, True)
else:
return Switch.CaseHandler(self, False)
class CaseHandler(object):
def __init__(self, case_instance, success):
self.case_instance = case_instance
self.success = success
def __rshift__(self, result):
if self.success:
self.case_instance.result = result
Code: Select all
x = 3
for case in Switch( x*x*x + x + 1 ):
case(29) >> "A"
case(30) >> "B"
case(31) >> "C"
case(32) >> "D"
print case.result
troyp wrote:no monkeypatching,
Code: Select all
>>> class Foo:
... pass
...
>>> foo = Foo()
>>> Foo.bar = lambda self: print("Hello")
>>> foo.bar()
Hello
Diadem wrote:Python isn't the best programming language in the world, because it's not a programming language at all. It's a scripting language.
Users browsing this forum: No registered users and 7 guests