Using a for loop for this in python

I am trying to use a for loop to formulate this:

  • expand('*+123456') should return '1*2+3*4+5*6'

  • expand('++123') should return '1+2+3'

  • expand('+*1234') should return '1+2*3+4'

A character is selected from the first two characters of a given string in an alternating manner and placed between outgoing digits.

Here is what I worked with:

 def expand(original): var = "" symbols = original[0:2] for i in range(len(original)): var = var + symbols + original[i] return var 

I understand that there must also be original[2:] , but I donโ€™t know where I can fit this here.

I am an amateur, and I have been trying for a long time to find out this question.

+4
source share
5 answers

Yes, your function would improve by adding [2:] there, but it might also lose range(len(original)) . Whenever you write range(len(something)) , you should step back and think about what you are actually trying to do.

In this case, you are looking for characters in a string, and you can get them more directly with for x in string . Here's a slightly improved version that takes these ideas into account:

 def expand(original): var = "" symbols = original[:2] for digit in original[2:]: var += (digit + symbols) return var 

This stops you from getting a weird mixture of characters at the beginning of the output, but it's still not perfect:

 >>> expand('+*1234') '1+*2+*3+*4+*' 

We need to find a way

  • character selection alternately and
  • leave them at the end of the line.

We can use itertools.cycle to process the first of them and a string slice for the second:

 from itertools import cycle def expand(original): var = "" symbols = cycle(original[:2]) for digit in original[2:]: var += (digit + next(symbols)) return var[:-1] 

This works, but at some point, someone is going to connect and tell you that you should not use + or += to create lines, because it is inefficient. If instead we create a list and then use str.join() to turn this into a string, we can improve things a bit:

 from itertools import cycle def expand(original): chars = [] symbols = cycle(original[:2]) for digit in original[2:]: chars.extend([digit, next(symbols)]) return "".join(chars[:-1]) 

However, we can do better. Instead of calling next(symbols) every time, we can use zip() to get the next character and the next digit a couple at a time:

 from itertools import cycle def expand(original): chars = [] for symbol, digit in zip(cycle(original[:2]), original[2:]): chars.extend([digit, symbol]) return "".join(chars[:-1]) 

... and that is probably enough :-)

EDIT . Since you said in a comment on another answer that you are not allowed to import anything from the standard library (rather silly IMO restrictions, but there), you can use the Python cycle() implementation described in the link earlier in this answer:

 def cycle(iterable): # cycle('ABCD') --> ABCDABCDABCD ... saved = [] for element in iterable: yield element saved.append(element) while saved: for element in saved: yield element 

... but you should probably be prepared to convince your teacher that you understand him, which means you need to understand yield .

+4
source

You can try something like that:

 a = "*+123456" def expand(input): symbols = input[:2] numbers = input[2:] result = "" for count, number in enumerate(numbers): # Switch symbol for every other iteration result += number + symbols[count%2] # There an extra symbol at the end, so remove it. return result[:-1] 

Here the sample runs in the interpreter:

 >>> a = "*+123456" >>> def expand(input): ... symbols = input[:2] ... numbers = input[2:] ... result = "" ... for count, number in enumerate(numbers): ... result += number + symbols[count%2] ... return result[:-1] ... >>> expand(a) '1*2+3*4+5*6' >>> a = "++123456" >>> expand(a) '1+2+3+4+5+6' 

In the code it should be noted:

enumerate - takes an iterable object and returns a tuple in the form of (index, value) .

input[:2] - take a fragment of an array of characters from the beginning to the element at position 2 (not inclusive)

input[2:] - take a fragment of an array of characters from position 2 to the end (inclusive)

list[:-1] - Take a picture from the beginning of the list to 1 item from the end of the list.

count%2 - Take the count (index) of the character in the array and divide it by 2, keeping the remainder. The result of this will vary between 0 and 1 each step of switching between two characters.

+3
source

You can use itertools to โ€œloopโ€ over operator characters, and then alternate (โ€œzipโ€) them with numbers:

 import itertools def expand(original): var = "" symbols = original[:2] numbers = original[2:] for symbol, number in zip(numbers[:-1], itertools.cycle(symbols)): var += symbol + number return var + numbers[-1] 

It is output:

  >>> expand ('* + 123456')
 '1 * 2 + 3 * 4 + 5 * 6'
 >>> expand ('++ 123')
 '1 + 2 + 3'
 >>> expand ('+ * 1234')
 '1 + 2 * 3 + 4'
+2
source

Here is one of the options for using the FOR loop that you wanted:

 def expand(x): p=x[:2] n=x[2:] s='' c=0 for i in n: s+=i s+=p[c] c=1-c return s[:-1] 

The idea is to split your string into the operator string p and the number string n, and then iterate over. The variable c changes from 0 to 1 and vice versa, so it constantly iterates over p (you can achieve the same with modulo). For more โ€œpythonicโ€ ways to do this, see Other Answers (I was going for lover clarity).

+1
source

The late answer, each of them is useful, but for some reason this aroused my interest:

 In [9]: from itertools import izip, cycle In [10]: def expand(s): ....: return ''.join(reduce(lambda x, y: x+y, izip(s[2:], cycle(s[:2]))))[:-1] ....: In [11]: expand('*-123') Out[11]: '1*2-3' In [12]: expand('+-123456') Out[12]: '1+2-3+4-5+6' 

I completely agree with what @Bitwise et al said - definitely not what you need, as it does not meet your limitations, so apologies for blocking the stream :)

For posterity, this takes the string in question and then uses the reduce function to combine the number with one of the alternating character strings. Then we trim the final character and return the result of join 'ed, which will be a string. Hope it will be useful in the future!

+1
source

Source: https://habr.com/ru/post/1443346/


All Articles