We can use for loop inside an array,
for example: arr = [i for i in range(10)]
I want to add all the digits of an number into array; can we use the same methodology and implement using while loop?
What you have shown is a list comprehension, not a loop inside an array.
There is no such thing that involves the while keyword.
It's possible to define a generator with a while loop and then use that generator in a list comprehension.
For example, this generates all digits of a non-negative integer (in reverse order):
def digits(n):
while True:
n, d = divmod(n, 10)
yield d
if n == 0:
break
arr = [i for i in digits(123)] # [3, 2, 1]
i want to add all the digits of an number into array can we sue the same methodology and implement using while loop?
No, you cannot do a similar thing with a while loop. The syntax [i for i in range(10)] is called a "list comprehension". If you google these words, you will find more information about how they work.
For the digits of a number, I suggest turning it into a string:
number = 12345
digits = str(number)
Now you can use digits like an array of digit characters:
print(digits[2]) # output: 3
for d in digits:
print(d)
If you want a list of digits as integers rather than characters:
digits = [int(c) for c in str(number)]
Related
First, I got this problem: how many words are there (counting all of them, even those that don't make sense) of 5 letters that have at least one I and at least two T's, but no K or Y?
First, I defined the alphabet, which has 24 letters ( k and y aren't counted). After that, i made a code to generate all possibilites
alphabet = list(range(1, 24))
for L in range(0, len(alphabet)+1):
for subset in itertools.permutations(alphabet, L):
I don't know how to use the data.
If a “brute force” method is enough for you, this will work:
import string
import itertools
alphabet = string.ascii_uppercase.replace("K", "").replace("Y", "")
count = 0
for word in itertools.product(alphabet, repeat = 5):
if "I" in word and word.count("T") >= 2:
count += 1
print (count)
It will print the result 15645.
Note that you have to use itertools.product(), because itertools.permutations() will not contain repeated occurences, so it will never contain “T” twice.
Edit: Alternatively, you can calculate the count with a list comprehension or a generator expression. It takes advantage of the fact that boolean True and False are equivalent to integer values 1 and 0, respectively.
count = sum(
"I" in word and word.count("T") >= 2
for word in itertools.product(alphabet, repeat = 5)
)
NB: Interestingly, the first solution (explicit for loop with counter += 1) runs about 15 % faster on my computer than the second solution (generator expression with sum()). Both require the same amount of memory (this is expected).
I have the following problem : From a list of strings, i have to take the first letters from all the strings, after (from back to front), i have to take the second letters, after the third letters from front to end and so on.
Example input :
['abcd', 'efgh', 'ijkl', 'mnop']
Output should be :
'aeimnjfbcgkoplhd'
Here I am so far, the first "for" is appending to the array : aeim and cgko
the second "for" is appending to the array: njfb and plhd. Anyway the order is not good, i need aeim + njfb + cgko + plhd
array = []
if len(list_of_strings[0]) % 2 == 0: # if we have strings with even number of letters
for j in range(len(list_of_strings[0]/2)): # range(2) in our example
for i in range(len(list_of_strings)): # range(4) in our example
array.append(list_of_strings[i][j*2])
for j in range(1, len(list_of_strings[0]), 2): # range(1, 4, 2) in our example
for i in range(len(list_of_strings) - 1, -1, -1): # range(3, -1, -1) in our example
array.append(list_of_strings[i][j])
Please help.
Thank you
You can use a simple one-liner using "unzip" (i.e. zip(*a)) and str.join:
a = ['abcd', 'efgh', 'ijkl', 'mnop']
b = ''.join(''.join(t[::1-2*(i%2)]) for i, t in enumerate(zip(*a)))
assert b == 'aeimnjfbcgkoplhd'
join can take a generator expression as an argument, in this case the generator expression is
''.join(t[::1-2*(i%2)]) for i, t in enumerate(zip(*a))
The expression
zip(*a)
unzips the strings in a, i.e. it returns a generator which yields tuples containing all first letters, all second letters, etc. of each string.
The indexing in
t[::1-2*(i%2)]
ensures that we reverse the order of the tuple every 2nd iteration.
EDIT
I benchmarked my one-liner vs. #cs95's answer, and performance of both is the same within error margins. I think in "real code" I'd hence prefer his solution for its higher clarity.
Think of the characters as elements in a 2D array:
a b c d
e f g h
i j k l
m n o p
We want to go in down on odd columns, then up on even columns, so we do something like this:
chars = []
for i in range(len(l[0])):
for w in l[::1 if i % 2 == 0 else -1]:
chars.append(w[i])
print(''.join(chars))
# aeimnjfbcgkoplhd
l[::1 if i % 2 == 0 else -1] will reverse the list for even columns so we're picking characters from the end. This is intuitive but ugly since slicing the list creates a shallow copy. We can do something a little more clever by using a mod to determine whether to iterate in reverse:
chars = []
for i in range(len(l[0])):
for j in range(len(l)) if i % 2 == 0 else reversed(range(len(l))):
chars.append(l[j][i])
print(''.join(chars))
# aeimnjfbcgkoplhd
Currently trying to get this to create all possible combinations of these 20 letters in a list, (without repeats)
letters = ['G','A','L','M','F','W','K','Q','E','S','P','V','I','C','Y','H','R','N','D','T']
combinations = [''.join(i) for i in itertools.combinations(letters,r=20)]
Output I'm looking for is a list like:
combinations = ['G','A','L','M','F','W','K','Q','E','S','P','V','I','C','Y','H','R','N','D','T',GG,GA,GL,GM... ...GALMFWKQESPVICYHRNDT]
You could use a nested loop in the list comprehension to iterate through all possible lengths:
letters = ['G','A','L','M','F','W','K','Q','E','S','P','V','I','C','Y','H','R','N','D','T']
combinations = [''.join(i) for j in range(1,len(letters) + 1) for i in itertools.combinations(letters,r=j)]
Here's one way:
letters = ['G','A','L','M','F','W','K','Q','E','S','P','V','I','C','Y','H','R','N','D','T']
def gen_combinations(opts):
for index in range(2 ** len(opts)):
mask = bin(index)[2:].zfill(len(opts))
selected = [o for (o,m) in zip(opts, mask) if m == '1']
yield ''.join(selected)
If you want only some of the possibilities:
for (i,x) in enumerate(gen_combinations(letters)):
print(x)
if i > 10: break
Output:
# The empty set
T
D
DT
N
NT
ND
NDT
R
RT
RD
RDT
If you want them all:
all_combinations = list(gen_combinations(letters))
print(len(all_combinations)) # 1048576
This uses a generator that looks at the binary representation of a (in this case) 20-bit number, and if the bit is 1, adds that item to the output list for that iteration.
There will be 2^len(opts) list elements -- in this case 2^20 -- all the possible combinations.
P.S. bin(i) is typically faster than doing bit manipulation, but I'm not sure that still holds with the added zfill.
I need to create a function that receives a positive integer number (n) and returns a string, using nested loops.
For example:
when n = 3 the returned string should be:
"1+2+3+..1+2+3+..1+2+3+.."
when n = 5 the returned string should be:
1+2+3+4+5+..1+2+3+4+5+..1+2+3+4+5+..1+2+3+4+5+..1+2+3+4+5+..
As an example, the following code fragment:
n = 5
res = addnestedloops(n)
print (res)
should produce the output:
1+2+3+4+5+..1+2+3+4+5+..1+2+3+4+5+..1+2+3+4+5+..1+2+3+4+5+..
Can't seem to find out how to return the string in which it counts upwards until the inputted number...
def themethod(n):
var toprint="";
var tmp;
if(n>0)tmp="1";
for(var i=2;i<=n;i++):
tmp+= "+".i;
for(var i=0;i<n;i++):
toprint += tmp;
print toprint;
I think what you are looking for is head-recursion in python
Here is the code which will let you achieve this
def recursive(n):
if n == 1:
return 1
else:
return str(recursive(n-1)) + "+"+str(n)
A nested loop is just a loop within a loop. If I understand you correctly, you need n strings concatenated, each containing n numbers.
I have a feeling this is a school assignment, so I wont give you the full answer, but I believe the nested loop construction you need is
for i in range(n):
for j in range(n):
# Construct the sub string here and append it to a result variable
Remember that the range function output is zero based, so range(3) produces 0, 1 and 2.
I don't however see why you need a nested loop, other than it should be a part of the assignment. You could just construct the sub string and repeat it n times with substring * n. For example 'hello' * 3 results in 'hellohellohello'.
Oh, and just to give you a bit more to think about, the one-liner solution for your problem is
('+'.join('{0:d}'.format(i+1) for i in range(n)) + '+..') * n
Whenever I use permutations, I have to create a list of the permutations because it returns a 'itertools.permutations object at 0x0190A5D0'. Then after I create the list, I have to combine the strings in each list so that I have the permutation I wanted originally. If it is a number, then I have to make them all integers again.
Two part question:
1) Is there an easier way to do a permutation and create the list of numbers?
2) Below I've created a permutation of a number with 5 digits. However, where I have '12345', I want the user to input their own number. Thus the formatting string b=['s%s%s...] will have to be n %s and n x. Anyone know how to do this?
(FYI my program is trying to find the next largest number with the same digits given a user's input so 12345 next largest is 12354)
Both questions were answered below please see both responses. Thanks!!!
def nexthighest():
from itertools import permutations
numb = str(12345)
a = list(permutations(numb))
b = ['%s%s%s%s%s' % xxxxx for xxxxx in a] #<-- this is where the n length problem occurs
c = list(map(int,b))
for i in c:
if i >12345:
print(i)
break
You don't need to build all those lists. Just loop over the return value from permutations, joining and parsing as an integer each permutation as it comes by:
def nexthigher(n):
for p in permutations(sorted(str(n))):
i = int("".join(p))
if i > n:
return i
I can answer part two for you:
b = ["".join(x) for x in a]