2011-08-04 3 views
1

Je suis un débutant en Python, en train de me former à partir de Google Code University. J'ai eu ce problème comme un exercice, et a été en mesure de le résoudre en utilisant la solution ci-dessous:Aidez-moi à simplifier ce code (Python)

# F. front_back 
# Consider dividing a string into two halves. 
# If the length is even, the front and back halves are the same length. 
# If the length is odd, we'll say that the extra char goes in the front half. 
# e.g. 'abcde', the front half is 'abc', the back half 'de'. 
# Given 2 strings, a and b, return a string of the form 
# a-front + b-front + a-back + b-back 
def front_back(a, b): 
    if len(a) % 2 == 0: 
    ad = len(a)/2 
    if len(b) % 2 == 0: 
     bd = len(b)/2 
    else: 
     bd = (len(b)/2) + 1 
    else: 
    ad = (len(a)/2) + 1 
    if len(b) % 2 == 0: 
     bd = len(b)/2 
    else: 
     bd = (len(b)/2) + 1 

    return a[:ad] + b[:bd] + a[ad:] + b[bd:] 

Cela produit la sortie correcte et résout le problème. Cependant, je suis en train de dupliquer la logique de séparer une ficelle uniformément ou d'ajouter le nombre impair à la première moitié, ce qui semble redondant. Il doit y avoir un moyen plus efficace de le faire. Le même contrôle et la même logique sont appliqués à a et b. N'importe qui?

Répondre

12
def front_back(a, b): 
    ad = (len(a) + 1) // 2 
    bd = (len(b) + 1) // 2 
    return a[:ad] + b[:bd] + a[ad:] + b[bd:] 

En utilisant // pour la division fait ce travail de code à la fois Python 2.x et 3.x.

+0

qui est assez, à peu près ce que je suis venu avec – nflacco

+1

Je ne comprends pas vraiment comment cela fonctionne, mais il ne .... Google . – Dan

+0

@Sven, pouvez-vous nous expliquer comment cela fonctionne? (en particulier l'opérateur '//') – OscarRyz

4

Eh bien, mettez-le dans une fonction séparée.

def front_back(string): 
    offset = len(string)/2 
    if len(string) % 2 != 0: 
     offset += 1 
    return string[:offset], string[offset:] 

def solution(a, b): 
    front_a, back_a = front_back(a) 
    front_b, back_b = front_back(b) 
    return front_a + back_a + front_b + back_b 
2

Vous pouvez obtenir l'indice maximum en utilisant ceil

In [1]: l = [1,2,3] 
In [2]: import math 
In [4]: math.ceil(len(l)/2.0) 
Out[4]: 2.0 
In [5]: l.append(4) 
In [6]: math.ceil(len(l)/2.0) 
Out[6]: 2.0 
In [7]: l.append(5) 
In [8]: math.ceil(len(l)/2.0) 
Out[8]: 3.0 
In [9]: l[0:3] 
Out[9]: [1, 2, 3] 
In [10]: l[3:] 
Out[10]: [4, 5] 
1
from math import ceil 

def front_back(a, b): 
    divide = lambda s: int(ceil(len(s)/2.0)) # or lambda s: (len(s) + 1) // 2 
    a_divide, b_divide = divide(a), divide(b) 
    return a[:a_divide] + b[:b_divide] + a[a_divide:] + b[b_divide:] 
3

Puisque vous ajoutez 1 à la longueur si elle est bizarre, et « bizarre » signifie que len(a)%2 == 1 ...

def front_back2(a, b): 
    ad = (len(a) + len(a)%2)/2 
    bd = (len(b) + len(b)%2)/2 
    return a[:ad]+b[:bd]+a[ad:]+b[bd:] 

Bien sûr, vous pourriez même condenser à une ligne juste pour coups de pied (même si, il est beaucoup moins lisible):

def front_back2(a, b): 
    return a[:(len(a)+len(a)%2)/2]+b[:(len(b)+len(b)%2)/2]+a[(len(a)+len(a)%2)/2:]+b[(len(b)+len(b)%2)/2:] 
1

Voici le mien:

def front_back(a, b) : 
    return of(a)[0] + of(b)[0] + of(a)[1] + of(b)[1] 

def of(s): 
    index = len(s)/2 + (1 if len(s) % 2 == 1 else 0) 
    return (s[ : index ] , s[ index : ]) 


print front_back('abcde','hola') 

Prints:

abchodela 
2

Mhh essayer de comprendre @Sven réponse que je suis ceci:

len(s) + 1/2 

vous donnera toujours l'indice correct.

Donc, si nous mettons que dans une fonction:

def d(s): 
    return (len(s) + 1)/2 

Nous pouvons l'utiliser dans la solution:

def front_back(a, b): 
    return a[:d(a)] + b[:d(b)] + a[d(a):] + b[d(b):] 

Ok, je l'ai maintenant.

Je ne suis pas tout à fait sûr quelle est la différence entre / et // si

+0

Cela a du sens.Je ne comprends toujours pas la différence entre/et // – Dan

+0

J'ai commenté la différence entre '/' et '//' en dessous de ma réponse. –