san1512
san1512

Reputation: 1023

Using len() in a string

How to find the length of the below string without using a variable?

string = "This is a sentence and it has %d characters" % len(string)

print string

This one doesn't work. Whats the proper way to code?

Upvotes: 2

Views: 2109

Answers (5)

martineau
martineau

Reputation: 123463

You can't take the length of the string until you assign something to it, so do that before the doing the substitution and then figure out how long the result will be with simple math:

POWERS_OF_TEN = {10**n for n in range(7)}  # handle strings over 10M chars long

string = "This is a sentence and it has %d characters"
length = len(string) - len('%d') + len("%d" % len(string))
correction = len(string)+1 in POWERS_OF_TEN
string %= length+correction
print(string)  # This is a sentence and it has 43 characters

The computations above correctly handle the situation where the length of the result is different than the length of the original string with"%d"in it.

This is illustrated by the following test code which shows the original string and its length, followed by the resulting string and both its actual and computed lengths for inputs of varying sizes—as you can see, the latter two values always match, including in the special case where adding one character made the resulting string two characters longer:

for i in range(0, 10+1):
    string = (''.join(chr(ord('A')+(d-1)%26) if d else ''
              for d in range(0, i+1))+ "%d")
    length = len(string) - len('%d') + len("%d" % len(string))
    correction = len(string)+1 in POWERS_OF_TEN
    string2 = string % (length+correction)
    print('{!r}, len: {} -> {!r}, length actual: {} vs computed: {}'.format(
          string, len(string), string2, len(string2), length))

Output:

'%d', len: 2 -> '1', length actual: 1 vs computed: 1
'A%d', len: 3 -> 'A2', length actual: 2 vs computed: 2
'AB%d', len: 4 -> 'AB3', length actual: 3 vs computed: 3
'ABC%d', len: 5 -> 'ABC4', length actual: 4 vs computed: 4
'ABCD%d', len: 6 -> 'ABCD5', length actual: 5 vs computed: 5
'ABCDE%d', len: 7 -> 'ABCDE6', length actual: 6 vs computed: 6
'ABCDEF%d', len: 8 -> 'ABCDEF7', length actual: 7 vs computed: 7
'ABCDEFG%d', len: 9 -> 'ABCDEFG9', length actual: 8 vs computed: 8
'ABCDEFGH%d', len: 10 -> 'ABCDEFGH10', length actual: 10 vs computed: 10
'ABCDEFGHI%d', len: 11 -> 'ABCDEFGHI11', length actual: 11 vs computed: 11
'ABCDEFGHIJ%d', len: 12 -> 'ABCDEFGHIJ12', length actual: 12 vs computed: 12

Upvotes: 1

PascalVKooten
PascalVKooten

Reputation: 21443

This is basically a constant in the way you state it.

If it would be partially variable, you would just have a constant which reflects the part that does not change e.g. len("This sentence has") + len("characters").

The variable part would simply be evaluated before posting such a string. At that point, a len(string) added with the constant part will yield the right answer.

Sometimes an answer does not need (much) code :-)

Upvotes: 0

Denis
Denis

Reputation: 136

Practically this doesn't work since string is referenced before assignment. Apart from that this will never work by design since in a transfered sense you're creating a recursion. You're trying to get the length of a string whose length depends on the length of the string itself (Huh?) To solve a problem like this, one could (!!!) solve that iterativelly:

l =42
while True:
    s = "This is a sentence and it has %d characters" % l
    if len(s)==l:
      break
    l = sample_new_length()

By selecting a proper sampling function, this could be solved.

Upvotes: 0

Raul Andres
Raul Andres

Reputation: 3806

In your sentence you'r trying to evaluate string lenght before assigning it any value

string = "This is a sentence and it has %d characters" % len(string)

You should consider where it's possible to do it i.e:

 string = "%d chars.." 

could expand equally to

 string = "9 chars.." 

And to:

 string = "10 chars.."

Upvotes: 2

user2357112
user2357112

Reputation: 280564

Hardcode the answer:

string = "This is a sentence and it has 43 characters"

For a more general case, you can use an iterative approximation:

base = "This sentence has %d characters"
n = 1
while len(base % n) != n:
    n = len(base % n)
string = base % n

Your code tries to get the length of a string that doesn't exist yet. That won't work. With a different input, there could even be multiple ways to fill in the blank:

string = "chars:  %d"

9 or 10? Who knows.

Upvotes: 0

Related Questions