1
\$\begingroup\$

I have this code:

Sorted=False
while not Sorted:
    Sorted=True
    for x,y in enumerate(List[:-1]):
        if List[x]>List[x+1]:
            List[x],List[x+1]=List[x+1],List[x]
            Sorted=False

However the use of

Sorted=True/False

being repeated is quite ugly and it would be much nicer to write the code is something similar to:

while True:
    for x,y in enumerate(List[:-1]):
        if List[x]>List[x+1]:
            List[x],List[x+1]=List[x+1],List[x]
            break
    else:break

The only problem is that breaking from the loop this early causes the loop to be repeated many more times taking up more time overall. Are there any ways around this to make the code more pythonic or do I just need to leave it as ugly as it is?

\$\endgroup\$
1
  • 3
    \$\begingroup\$ Hi and welcome to CodeReview. Unfortunately, List is missing. While its name indicates that it's a usual Python list, several other collections in Python also provide an iterator interface as well as (range-based) indexing. Also, keep in mind that while reviewers might answer additional questions, it's not mandatory. Asking for other ways is inherently off-topic, so you might want to remove your question or rephrase it into a concern. Last but not least, you probably want to tag your question with reinventing-the-wheel and comparative-review. I hope you get nice reviews :). \$\endgroup\$ – Zeta Apr 22 at 21:18
2
\$\begingroup\$

One approach is to move most of the logic into a helper function that does the swapping and returns the N of swaps. The outer part of the algorithm then reduces to almost nothing.

While you're at it: (1) use conventional names for Python variables (lowercase for variables, capitalized for classes, uppercase for constants); (2) let your operators breathe for readability, (3) take full advantage of enumerate(), which gives both index and value (x1), (4) use convenience variables to make code more readable (x2 rather that repeated uses of xs[i + 1]); (5) look for ways to pick simple variable names that help the reader understand the algorithm (i for an index; xs for a list of values; x1 and x2 for individual values that are being swapped) rather than purely abstract variable names that convey nothing substantive to the reader (List, x for an index, and y for a value); and (6) put your sort in a proper function.

def bubble_sort(xs):
    while bubble(xs):
        pass

def bubble(xs):
    n_swaps = 0
    for i, x1 in enumerate(xs[:-1]):
        x2 = xs[i + 1]
        if x1 > x2:
            xs[i] , xs[i + 1] = x2, x1
            n_swaps += 1
    return n_swaps

vals = [9, 3, 4, 2, 6, 8, 10, 1]
bubble_sort(vals)
print(vals)
\$\endgroup\$
3
  • \$\begingroup\$ Nice review. But how xs would help the reader to understand that it's a list of values? \$\endgroup\$ – Marc Apr 23 at 1:12
  • 1
    \$\begingroup\$ Also, counting the swaps is unnecessary, a flag would be enough. \$\endgroup\$ – Marc Apr 23 at 2:05
  • \$\begingroup\$ @Marc Yes, adjust as needed. The truth evaluation is the same and bubble() could be used for something else in our bUbBle-SoRt library. More seriously, xs is a conventional name for exactly this purpose: one x, many xs (especially in contexts where the values are generic in some sense). It's ubiquitous in functional programming, for example, and works great in Python -- if applied with good sense. \$\endgroup\$ – FMc Apr 23 at 2:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.