Skip to main content
Add not on the original question
Source Link
John K.
  • 265
  • 1
  • 6

First of all, whenever you see this ... this is a big no-no:

'9'*work_dict[9] + '8'*work_dict[8] + '7'*work_dict[7] +
'6'*work_dict[6] + '5'*work_dict[5] + '4'*work_dict[4] +
'3'*work_dict[3] + '2'*work_dict[2] + '1'* work_dict[1] +
'0'*work_dict[0]

it could be replaced by a simple

''.join(str(i) * work_dict[i] for i in reversed(range(10)))

Of course, the initialization of the work_dict is similar. And in fact, you don't need to initialize it if you take care to use dict.get instead of dict[]:

work_dict[number] = work_dict[number] + 1
# is equivalent to
work_dict[number] = work_dict.get(number, 0) + 1  # default to 0 if not in dict

Ps., whenever you are counting something, consider using collections.Counter.


Warning: The rest of this answer tries to address the problem that OP say they are solving in the comments to the question. However, it is not certain that the understanding of the problem by the OP is correct. From here on, we assume that you are allowed to shuffle all the input digits, whereas the original problem probably only allows shuffling around the numbers.


If you want to have it as compact and "functional" as possible, it would be much easier to just sort the entire input and output it:

def maximum_number(lst):
    return int(''.join(sorted(''.join(str(x) for x in lst), reverse=True)))

However, note that this doesn't work on the empty list (which might be okay, depending on the specification of the function).

It should also be mentioned that

  1. it is harder to write than the "manual loop" variant, which can be important in an interview
  2. it might be harder to read and thus to debug, but I believe that this is up to the eye of the beholder to determine

For complexity, this is O(n log n) whereas the optimal algorithm has running time O(n). We again see the trade-off between running time and readability.

Here is an O(n) algorithm using Counter:

from collections import Counter
def maximum_number(lst):
    counter = Counter()
    for elt in lst:
        counter += Counter(str(elt))
    return int("".join(str(i) * counter[str(i)] for i in range(9, -1, -1)))

First of all, whenever you see this ... this is a big no-no:

'9'*work_dict[9] + '8'*work_dict[8] + '7'*work_dict[7] +
'6'*work_dict[6] + '5'*work_dict[5] + '4'*work_dict[4] +
'3'*work_dict[3] + '2'*work_dict[2] + '1'* work_dict[1] +
'0'*work_dict[0]

it could be replaced by a simple

''.join(str(i) * work_dict[i] for i in reversed(range(10)))

Of course, the initialization of the work_dict is similar. And in fact, you don't need to initialize it if you take care to use dict.get instead of dict[]:

work_dict[number] = work_dict[number] + 1
# is equivalent to
work_dict[number] = work_dict.get(number, 0) + 1  # default to 0 if not in dict

Ps., whenever you are counting something, consider using collections.Counter.


If you want to have it as compact and "functional" as possible, it would be much easier to just sort the entire input and output it:

def maximum_number(lst):
    return int(''.join(sorted(''.join(str(x) for x in lst), reverse=True)))

However, note that this doesn't work on the empty list (which might be okay, depending on the specification of the function).

It should also be mentioned that

  1. it is harder to write than the "manual loop" variant, which can be important in an interview
  2. it might be harder to read and thus to debug, but I believe that this is up to the eye of the beholder to determine

For complexity, this is O(n log n) whereas the optimal algorithm has running time O(n). We again see the trade-off between running time and readability.

Here is an O(n) algorithm using Counter:

from collections import Counter
def maximum_number(lst):
    counter = Counter()
    for elt in lst:
        counter += Counter(str(elt))
    return int("".join(str(i) * counter[str(i)] for i in range(9, -1, -1)))

First of all, whenever you see this ... this is a big no-no:

'9'*work_dict[9] + '8'*work_dict[8] + '7'*work_dict[7] +
'6'*work_dict[6] + '5'*work_dict[5] + '4'*work_dict[4] +
'3'*work_dict[3] + '2'*work_dict[2] + '1'* work_dict[1] +
'0'*work_dict[0]

it could be replaced by a simple

''.join(str(i) * work_dict[i] for i in reversed(range(10)))

Of course, the initialization of the work_dict is similar. And in fact, you don't need to initialize it if you take care to use dict.get instead of dict[]:

work_dict[number] = work_dict[number] + 1
# is equivalent to
work_dict[number] = work_dict.get(number, 0) + 1  # default to 0 if not in dict

Ps., whenever you are counting something, consider using collections.Counter.


Warning: The rest of this answer tries to address the problem that OP say they are solving in the comments to the question. However, it is not certain that the understanding of the problem by the OP is correct. From here on, we assume that you are allowed to shuffle all the input digits, whereas the original problem probably only allows shuffling around the numbers.


If you want to have it as compact and "functional" as possible, it would be much easier to just sort the entire input and output it:

def maximum_number(lst):
    return int(''.join(sorted(''.join(str(x) for x in lst), reverse=True)))

However, note that this doesn't work on the empty list (which might be okay, depending on the specification of the function).

It should also be mentioned that

  1. it is harder to write than the "manual loop" variant, which can be important in an interview
  2. it might be harder to read and thus to debug, but I believe that this is up to the eye of the beholder to determine

For complexity, this is O(n log n) whereas the optimal algorithm has running time O(n). We again see the trade-off between running time and readability.

Here is an O(n) algorithm using Counter:

from collections import Counter
def maximum_number(lst):
    counter = Counter()
    for elt in lst:
        counter += Counter(str(elt))
    return int("".join(str(i) * counter[str(i)] for i in range(9, -1, -1)))
remove `get` on counter
Source Link
John K.
  • 265
  • 1
  • 6

First of all, whenever you see this ... this is a big no-no:

'9'*work_dict[9] + '8'*work_dict[8] + '7'*work_dict[7] +
'6'*work_dict[6] + '5'*work_dict[5] + '4'*work_dict[4] +
'3'*work_dict[3] + '2'*work_dict[2] + '1'* work_dict[1] +
'0'*work_dict[0]

it could be replaced by a simple

''.join(str(i) * work_dict[i] for i in reversed(range(10)))

Of course, the initialization of the work_dict is similar. And in fact, you don't need to initialize it if you take care to use dict.get instead of dict[]:

work_dict[number] = work_dict[number] + 1
# is equivalent to
work_dict[number] = work_dict.get(number, 0) + 1  # default to 0 if not in dict

Ps., whenever you are counting something, consider using collections.Counter.


If you want to have it as compact and "functional" as possible, it would be much easier to just sort the entire input and output it:

def maximum_number(lst):
    return int(''.join(sorted(''.join(str(x) for x in lst), reverse=True)))

However, note that this doesn't work on the empty list (which might be okay, depending on the specification of the function).

It should also be mentioned that

  1. it is harder to write than the "manual loop" variant, which can be important in an interview
  2. it might be harder to read and thus to debug, but I believe that this is up to the eye of the beholder to determine

For complexity, this is O(n log n) whereas the optimal algorithm has running time O(n). We again see the trade-off between running time and readability.

Here is an O(n) algorithm using Counter:

from collections import Counter
def maximum_number(lst):
    counter = Counter()
    for elt in lst:
        counter += Counter(str(elt))
    return int("".join(str(i) * counter.get(strcounter[str(i), 0)] for i in range(9, -1, -1)))

First of all, whenever you see this ... this is a big no-no:

'9'*work_dict[9] + '8'*work_dict[8] + '7'*work_dict[7] +
'6'*work_dict[6] + '5'*work_dict[5] + '4'*work_dict[4] +
'3'*work_dict[3] + '2'*work_dict[2] + '1'* work_dict[1] +
'0'*work_dict[0]

it could be replaced by a simple

''.join(str(i) * work_dict[i] for i in reversed(range(10)))

Of course, the initialization of the work_dict is similar. And in fact, you don't need to initialize it if you take care to use dict.get instead of dict[]:

work_dict[number] = work_dict[number] + 1
# is equivalent to
work_dict[number] = work_dict.get(number, 0) + 1  # default to 0 if not in dict

Ps., whenever you are counting something, consider using collections.Counter.


If you want to have it as compact and "functional" as possible, it would be much easier to just sort the entire input and output it:

def maximum_number(lst):
    return int(''.join(sorted(''.join(str(x) for x in lst), reverse=True)))

However, note that this doesn't work on the empty list (which might be okay, depending on the specification of the function).

It should also be mentioned that

  1. it is harder to write than the "manual loop" variant, which can be important in an interview
  2. it might be harder to read and thus to debug, but I believe that this is up to the eye of the beholder to determine

For complexity, this is O(n log n) whereas the optimal algorithm has running time O(n). We again see the trade-off between running time and readability.

Here is an O(n) algorithm using Counter:

from collections import Counter
def maximum_number(lst):
    counter = Counter()
    for elt in lst:
        counter += Counter(str(elt))
    return int("".join(str(i) * counter.get(str(i), 0) for i in range(9, -1, -1)))

First of all, whenever you see this ... this is a big no-no:

'9'*work_dict[9] + '8'*work_dict[8] + '7'*work_dict[7] +
'6'*work_dict[6] + '5'*work_dict[5] + '4'*work_dict[4] +
'3'*work_dict[3] + '2'*work_dict[2] + '1'* work_dict[1] +
'0'*work_dict[0]

it could be replaced by a simple

''.join(str(i) * work_dict[i] for i in reversed(range(10)))

Of course, the initialization of the work_dict is similar. And in fact, you don't need to initialize it if you take care to use dict.get instead of dict[]:

work_dict[number] = work_dict[number] + 1
# is equivalent to
work_dict[number] = work_dict.get(number, 0) + 1  # default to 0 if not in dict

Ps., whenever you are counting something, consider using collections.Counter.


If you want to have it as compact and "functional" as possible, it would be much easier to just sort the entire input and output it:

def maximum_number(lst):
    return int(''.join(sorted(''.join(str(x) for x in lst), reverse=True)))

However, note that this doesn't work on the empty list (which might be okay, depending on the specification of the function).

It should also be mentioned that

  1. it is harder to write than the "manual loop" variant, which can be important in an interview
  2. it might be harder to read and thus to debug, but I believe that this is up to the eye of the beholder to determine

For complexity, this is O(n log n) whereas the optimal algorithm has running time O(n). We again see the trade-off between running time and readability.

Here is an O(n) algorithm using Counter:

from collections import Counter
def maximum_number(lst):
    counter = Counter()
    for elt in lst:
        counter += Counter(str(elt))
    return int("".join(str(i) * counter[str(i)] for i in range(9, -1, -1)))
update to sort(reverse=True), add O(n) algorithm using Counter
Source Link
John K.
  • 265
  • 1
  • 6

First of all, whenever you see this ... this is a big no-no:

'9'*work_dict[9] + '8'*work_dict[8] + '7'*work_dict[7] +
'6'*work_dict[6] + '5'*work_dict[5] + '4'*work_dict[4] +
'3'*work_dict[3] + '2'*work_dict[2] + '1'* work_dict[1] +
'0'*work_dict[0]

it could be replaced by a simple

''.join(str(i) * work_dict[i] for i in reversed(range(10)))

Of course, the initialization of the work_dict is similar. And in fact, you don't need to initialize it if you take care to use dict.get instead of dict[]:

work_dict[number] = work_dict[number] + 1
# is equivalent to
work_dict[number] = work_dict.get(number, 0) + 1  # default to 0 if not in dict

Ps., whenever you are counting something, consider using collections.Counter.


If you want to have it as compact and "functional" as possible, it would be much easier to just sort the entire input and output it:

def maximum_number(lst):
    return int(''.join(sorted(''.join(str(x) for x in lst), reverse=True)))

However, note that this doesn't work on the empty list (which might be okay, depending on the specification of the function).

It should also be mentioned that

  1. it is harder to write than the "manual loop" variant, which can be important in an interview
  2. it might be harder to read and thus to debug, but I believe that this is up to the eye of the beholder to determine

For complexity, this is O(n log n) whereas the optimal algorithm has running time O(n). We again see the trade-off between running time and readability.

Here is an O(n) algorithm using Counter:

from collections import Counter
def maximum_number(lst):
    counter = Counter()
    for elt in lst:
        counter += Counter(str(elt))
    return int("".join(str(i) * counter.get(str(i), 0) for i in range(9, -1, -1)))

First of all, whenever you see this ... this is a big no-no:

'9'*work_dict[9] + '8'*work_dict[8] + '7'*work_dict[7] +
'6'*work_dict[6] + '5'*work_dict[5] + '4'*work_dict[4] +
'3'*work_dict[3] + '2'*work_dict[2] + '1'* work_dict[1] +
'0'*work_dict[0]

it could be replaced by a simple

''.join(str(i) * work_dict[i] for i in reversed(range(10)))

Of course, the initialization of the work_dict is similar. And in fact, you don't need to initialize it if you take care to use dict.get instead of dict[]:

work_dict[number] = work_dict[number] + 1
# is equivalent to
work_dict[number] = work_dict.get(number, 0) + 1  # default to 0 if not in dict

If you want to have it as compact and "functional" as possible, it would be much easier to just sort the entire input and output it:

def maximum_number(lst):
    return int(''.join(sorted(''.join(str(x) for x in lst), reverse=True)))

However, note that this doesn't work on the empty list (which might be okay, depending on the specification of the function).

It should also be mentioned that

  1. it is harder to write than the "manual loop" variant, which can be important in an interview
  2. it might be harder to read and thus to debug, but I believe that this is up to the eye of the beholder to determine

First of all, whenever you see this ... this is a big no-no:

'9'*work_dict[9] + '8'*work_dict[8] + '7'*work_dict[7] +
'6'*work_dict[6] + '5'*work_dict[5] + '4'*work_dict[4] +
'3'*work_dict[3] + '2'*work_dict[2] + '1'* work_dict[1] +
'0'*work_dict[0]

it could be replaced by a simple

''.join(str(i) * work_dict[i] for i in reversed(range(10)))

Of course, the initialization of the work_dict is similar. And in fact, you don't need to initialize it if you take care to use dict.get instead of dict[]:

work_dict[number] = work_dict[number] + 1
# is equivalent to
work_dict[number] = work_dict.get(number, 0) + 1  # default to 0 if not in dict

Ps., whenever you are counting something, consider using collections.Counter.


If you want to have it as compact and "functional" as possible, it would be much easier to just sort the entire input and output it:

def maximum_number(lst):
    return int(''.join(sorted(''.join(str(x) for x in lst), reverse=True)))

However, note that this doesn't work on the empty list (which might be okay, depending on the specification of the function).

It should also be mentioned that

  1. it is harder to write than the "manual loop" variant, which can be important in an interview
  2. it might be harder to read and thus to debug, but I believe that this is up to the eye of the beholder to determine

For complexity, this is O(n log n) whereas the optimal algorithm has running time O(n). We again see the trade-off between running time and readability.

Here is an O(n) algorithm using Counter:

from collections import Counter
def maximum_number(lst):
    counter = Counter()
    for elt in lst:
        counter += Counter(str(elt))
    return int("".join(str(i) * counter.get(str(i), 0) for i in range(9, -1, -1)))
update to sort(reverse=True)
Source Link
John K.
  • 265
  • 1
  • 6
Loading
added 255 characters in body
Source Link
John K.
  • 265
  • 1
  • 6
Loading
Source Link
John K.
  • 265
  • 1
  • 6
Loading