This question already has answers here:
Convert list of ints to one number?
(19 answers)
Closed 5 years ago.
I want to generate a random 4 digit number in which none of the digits are repeated.
import random
sets = random.sample(range(0,9), 4)
This generates a random set of 4 digits but I want this as an integer. how do I do that?
(Assuming OP meant all the digits)
Instead of using numbers and have to manipulate to str and back to int, just start with ascii digits:
>>> import string
>>> ''.join(random.sample(string.digits, 4))
'4561'
You can convert to int() if necessary.
It's unclear what the OP intends to do if the first digit is 0.
For a purely numerical approach you can use functools.reduce:
>>> import functools as ft
>>> ft.reduce(lambda s, d: 10*s + d, random.sample(range(10), 4))
2945
You can do this by converting each digit to a string, joining them, and casting them as an integer.
int("".join(map(str,random.sample(range(0,9),4))))
if you need to generate 4 digit number, just for knowledge purpose use.
As suggested by AChampion this solution can contain duplicates
from random import randint
randint(1000, 9999)
Use bernie Solution to generate a random 4 digit number in which none of the digits are repeated.
int("".join(map(str,random.sample(range(0,9),4))))
In case if you want potentially infinite sequence of numbers with 4 unique digits (or any other condition – write your own)
import random
def numbers_gen(left_end, right_end):
while True:
yield random.randint(left_end, right_end)
def are_digits_unique(number):
number_string = str(number)
return list(set(number_string)) == list(number_string)
four_digits_numbers_gen = number_gen(left_end=1000,
right_end=9999)
four_digits_numbers_with_unique_digits_gen = filter(are_digits_unique,
four_digits_numbers_gen)
Works only in Python 3 because filter returns iterator-object (in Python 2.7 it returns list, more at docs)
You can multiply with powers of 10:
sum(10**a*b for a, b in enumerate(reversed(sets)))
This works as long as the first element of sets is not zero.
You could try:
import random
my_set = set()
while len(my_set) < 4:
x = random.choice(range(0,9))
my_set.add(x)
my_num = int("".join(map(str, my_set)))
One line:
int("".join(random.sample("0123456789",4)))
Related
This question already has answers here:
How do I compare version numbers in Python?
(16 answers)
Closed 6 years ago.
I want to get the maximum value from a list.
List = ['1.23','1.8.1.1']
print max(List)
If I print this I'm getting 1.8.1.1 instead of 1.23.
What I am doing wrong?
The easiest way is, to use tuple comparison.
Say:
versions = ['1.23','1.8.1.1']
def getVersionTuple(v):
return tuple(map(int, v.strip().split('.')))
Now you can use, print(max(map(getVersionTuple, versions))) to get the maximum.
EDIT:
You can use '.'.join(map(str, m)) to get the original string (given m holds the max tuple).
These aren't numbers, they are strings, and as such they are sorted lexicographically. Since the character 8 comes after 2, 1.8.1.1 is returned as the maximum.
One way to solve this is to write your own comparing function which takes each part of the string as an int and compares them numerically:
def version_compare(a, b):
a_parts = a.split('.')
b_parts = b.split('.')
a_len = len(a_parts)
b_len = len(b_parts)
length = min(a_len, b_len)
# Compare the parts one by one
for i in range(length):
a_int = int(a_parts[i])
b_int = int(b_parts[i])
# And return on the first nonequl part
if a_int != b_int:
return a_int - b_int
# If we got here, the longest list is the "biggest"
return a_len - b_len
print sorted(['1.23','1.8.1.1'], cmp=version_compare, reverse=True)[0]
A similar approach - assuming these strings are version numbers - is to turn the version string to an integer list:
vsn_list=['1.23', '1.8.1.1']
print sorted( [ [int(v) for v in x.split(".")] for x in vsn_list ] )
When you compare strings, they are compared character by character so any string starting with '2' will sort before a string starting with '8' for example.
This question already has answers here:
How to check if a input is in binary format(1 and 0)?
(8 answers)
Closed 7 years ago.
I'm trying to create a program that checks if each digit of a given number is less than 2, possibly using
range(len(a)):
def is_bin(number):
try:
int(str(number), 2)
except ValueError:
return False
return True
You can convert number to string and check like this:
all(int(c) < 2 for c in str(n))
For example:
>>> all(int(c) < 2 for c in str(1011))
True
>>> all(int(c) < 2 for c in str(1211))
False
You can try this
num = 123457
>>>all(int(i)<2 for i in str(num))
False
num = 11011
>>>all(int(i)<2 for i in str(num))
True
Python is dynamically typed, so this is relatively easy to do. I would suggest converting your integer into a string, then iterating through the string and checking each digit.
Using that method, the code would probably look something like:
your_number_string = str(your_number)
for d in range(0, len(your_number_string)):
i = your_number_string[d]
if (int(i) > 2):
raise new Exception("Digit " + str(i) + "is not less than 2")
Couple things to note with this: It's bad practice to throw bare Exceptions. If you like the exception route, then extend the exception class and make your own. This also assumes that your number is a valid integer. Finally, this also will only alert you for the first digit larger than two, it won't tell you about any subsequent ones that also are larger than 2. This will require some adjustments for negative numbers and floats.
Could use the good ol' fashioned method :) just take your number and extract each digit and then update your number.
while yournumber != 0 :
digit = yournumber % 10
yournumber = younumber / 10
if digit < 2
do stuff
but I'm sure there are easier (maybe not as fast) ways.
At the moment, all solutions depend on converting the number to a string. While that works, you could do it completely numerically:
def check_digits(nbr, max=1):
nbr = abs(nbr) # only look at a positive numbers
while nbr != 0:
nbr, rem = divmod(nbr, 10)
if rem > max: return False
return True
The trick here is that each time the digit furthest to the right gets inspected. Once that's done, the number gets divided by 10, ignoring the remainder. So 1201 becomes 120, which becomes 12 and the cycle stops there, because divmod(12, 10) is (1, 2), and the remainder, 2, is bigger than your maximum digit.
Note that TigerhawkT3's answer and #John La Rooy's comment probably nailed it (upvoted) as it is by far the most Pythonic solution. All others, including mine, work for various programming languages, TigerhawkT3's solution uses Python exceptions to good effect.
I want to know how can I add these numbers in Python by using a loop? Thanks
num=input("Enter your number: ")
ansAdd= int(str(num)[7])+int(str(num)[5])+int(str(num)[3])+int(str(num)[1])
print....
you want to do it using a loop, here you go:
ansAdd = 0
for x in [7,5,3,1]:
ansAdd += int(str(num)[x])
However, using list comprehension is more pythonic
>>> s = '01234567'
>>> sum(map(int, s[1::2]))
16
Here is how it works:
s[1::2] takes a slice of the string starting at index 1 to the end of the string stepping by 2. For more information on slices see the Strings section of the Python Tutorial.
map takes a function and an iterable (strings are iterable) and applies the function to each item, returning a list of the results. Here we use map to convert each string-digit to an int.
sum takes an iterable and sums it.
If you want to do this without the sum and map builtins, without slices, and with an explicit for-loop:
>>> s = '01234567'
>>> total = 0
>>> for i in range(1, len(s), 2):
... total += int(s[i])
...
>>> total
16
>>> num=input()
12345678
>>> sum(map(int,num[:8][1::2]))
20
here num[:8][1::2] returns only the numbers required for sum(), num[:8] makes sure only the elemnets up to index 7 are used in calculation and [1::2] returns 1,3,5,7
>>> num[:8][1::2]
>>> '2468'
It seems you want to sum odd-numbered digits from user input. To do it with a loop:
num_str = raw_input("Enter your number: ")
ansAdd = 0
for digit in num_str[1::2]:
ansAdd += int(digit)
(The syntax [1::2] is python's string slicing -- three numbers separated by : that indicates start index, stop index and step. An omitted value tells python to grab as much as it can.)
There's a better way to do this without using a traditional loop:
num_str = raw_input("Enter your number: ")
ansAdd = sum(int(digit) for digit in num_str[1::2])
In python 2, input executes the entered text as python code and returns the result, which is why you had to turn the integer back into a string using str.
It is considered a security risk to use input in python 2, since the user of your script can enter any valid python code, and it will be executed, no questions asked. In python 3 raw_input has been renamed to input, and the old input was removed (use eval(input()) instead).
How to generate random numbers in python having(11 to 20 digits) that should not start with 0 in beginning?
e.g:23418915901
def key_more_than_10():
v=random.randint(11,20)
char_set = string.digits+string.digits+string.digits
s= ''.join(random.sample(char_set,v))
return s
I used this code but since string.digits(give numbers between 0 to 9) it doesnt help me?
There should be an equal possibility to have 11 digits number and a 20 digits number.
Simple:
>>> help(random.randint)
Help on method randint in module random:
randint(self, a, b) method of random.Random instance
Return random integer in range [a, b], including both end points.
>>> random.randint(10000000000,99999999999999999999)
35677750742418249489
Of course, if you actually want a string (not sure why you would), you could wrap a str() around the whole thing:
>>> str(random.randint(1000000000,99999999999999999999))
'91138793919270489115'
How about a literal translation of what you want into code:
import random
DIGITS = '0123456789'
ndigits = random.randint(11, 20)
digits = [random.choice(DIGITS[1:])] + [random.choice(DIGITS) for i in xrange(ndigits-1)]
print int(''.join(digits))
The number of digits in the almost random result should be uniformly distributed between 11..20. Not quite random because restricting the first digit to a something other than a zero precludes it.
I would choose randrange for this
Help on method randrange in module random:
randrange(self, start, stop=None, step=1, int=<type 'int'>, default=None, maxwidth=9007199254740992L) method of random.Random instance
Choose a random item from range(start, stop[, step]).
This fixes the problem with randint() which includes the
endpoint; in Python this is usually not what you want.
Do not supply the 'int', 'default', and 'maxwidth' arguments.
so
random.randrange(1e11, 1e20)
will do what you want. For a string use this
str(random.randrange(1e11, 1e20))
I need to generate a string with n characters in Python. Is there a one line answer to achieve this with the existing Python library? For instance, I need a string of 10 letters:
string_val = 'abcdefghij'
To simply repeat the same letter 10 times:
string_val = "x" * 10 # gives you "xxxxxxxxxx"
And if you want something more complex, like n random lowercase letters, it's still only one line of code (not counting the import statements and defining n):
from random import choice
from string import ascii_lowercase
n = 10
string_val = "".join(choice(ascii_lowercase) for i in range(n))
The first ten lowercase letters are string.lowercase[:10] (if you have imported the standard library module string previously, of course;-).
Other ways to "make a string of 10 characters": 'x'*10 (all the ten characters will be lowercase xs;-), ''.join(chr(ord('a')+i) for i in xrange(10)) (the first ten lowercase letters again), etc, etc;-).
if you just want any letters:
'a'*10 # gives 'aaaaaaaaaa'
if you want consecutive letters (up to 26):
''.join(['%c' % x for x in range(97, 97+10)]) # gives 'abcdefghij'
Why "one line"? You can fit anything onto one line.
Assuming you want them to start with 'a', and increment by one character each time (with wrapping > 26), here's a line:
>>> mkstring = lambda(x): "".join(map(chr, (ord('a')+(y%26) for y in range(x))))
>>> mkstring(10)
'abcdefghij'
>>> mkstring(30)
'abcdefghijklmnopqrstuvwxyzabcd'
This might be a little off the question, but for those interested in the randomness of the generated string, my answer would be:
import os
import string
def _pwd_gen(size=16):
chars = string.letters
chars_len = len(chars)
return str().join(chars[int(ord(c) / 256. * chars_len)] for c in os.urandom(size))
See these answers and random.py's source for more insight.
If you can use repeated letters, you can use the * operator:
>>> 'a'*5
'aaaaa'