2

Is there a better way to insert variables into a string?

Something, say, less repetitive than...

with open('zlog.txt', 'a') as log:
    log.write('[ %s ] Finished scrolling.\n[ %s ] #%s clicks.\n[ %s ] Number of Elements: %s\n' % (finish_time, finish_time, str(x), finish_time, str(len(elements))))

I am constantly reusing finish_time in order to timestamp entries in a log.

... % (finish_time, finish_time, str(x), finish_time, str(len(elements)))

oldboy
  • 5,729
  • 6
  • 38
  • 86
  • @Dark my question isn't so much about inserting variables into a string, as the title may suggest, but rather about the most concise way(s) to insert **repeated** variables – oldboy Jun 26 '18 at 06:06
  • A really simple option is to use do `t = finish_time` and then you can use `t, t, x, t, len(elements)`. (Also, you don't need `str(x)` or `str(len(elements))`—passing an argument to a `%s` automatically calls `str` on it.) – abarnert Jun 26 '18 at 06:09
  • @abarnert i'd rather have a more descriptive name for the variable, but thanks for the info about the string conversion! – oldboy Jun 26 '18 at 06:10
  • @Anthony check the updated links :). – Bharath M Shetty Jun 26 '18 at 06:10
  • But you can have _both_ names for the same value. – abarnert Jun 26 '18 at 06:11
  • @Dark which updated link?! – oldboy Jun 26 '18 at 06:12
  • @abarnert you've lost me. what do you mean both names for the same value? – oldboy Jun 26 '18 at 06:12
  • 1
    @Anthony there are two links in the duplicates you can check both. The latter is the one you wanted. – Bharath M Shetty Jun 26 '18 at 06:12
  • After `t = finish_time`, you can refer to the value as `finish_time` when you want to be explicit, or as `t` when you want to be concise. Either way, it's the same value, so you can use whichever name is appropriate each time. – abarnert Jun 26 '18 at 06:14
  • @abarnert ohhhh, you're talking about double binding it. yeah, w/e :) – oldboy Jun 26 '18 at 06:15

3 Answers3

3

Use positional argument specifier in format:

>>> '{0} {0}, {1}!'.format('hello', 'world')
'hello hello, world!'
>>>
blhsing
  • 91,368
  • 6
  • 71
  • 106
  • Oh, wow, that's awesome! Would the syntax be `write(...).formate(...)`? – oldboy Jun 26 '18 at 06:01
  • 1
    In your example, it would be something like `log.write('[ {0} ] ... [ {0} ] ... [ {1} ] ...'.format(finish_time, x, ...))`. Remember `format` is a method of `str`, not a method of an object returned by `write`. – blhsing Jun 26 '18 at 06:04
  • This has to be the best answer yet. I'll mark it as the answer if nothing else ends up coming in. – oldboy Jun 26 '18 at 06:05
  • Do the indexes have to begin at `0` or is the number arbitrary? – oldboy Jun 26 '18 at 06:08
  • Yeah the index has to start from `0` to match the position of the arguments in `format` indeed. – blhsing Jun 26 '18 at 06:10
  • Hm... it's not working for me. Do the "template literals" have to be in the correct order (i.e. `{0} {0} {1} {1} {1} {2}` or can they be unordered `{0} {1} {0} {0} {2}`? – oldboy Jun 26 '18 at 06:14
  • 1
    It can be any order, so `'{0}, {1}, {0}!'.format('hello', 'world')` would yield `'hello, world, hello!'`, for example. – blhsing Jun 26 '18 at 06:15
  • hm... then was this not yet implemented in 2.7? – oldboy Jun 26 '18 at 06:17
  • It's available in 2.7 for sure. In fact, that's what I am using. What error or output are you getting? – blhsing Jun 26 '18 at 06:18
  • `TypeError: not all arguments converted during string formatting` don't understand why it's not converting all elements :/ – oldboy Jun 26 '18 at 06:20
  • oh, i'm retarded, it's cuz i forgot to change ` % ` to `.format` lol... – oldboy Jun 26 '18 at 06:22
  • I was typing the same. :-) That particular error comes from `%`, not `format`. Glad you got it working. – blhsing Jun 26 '18 at 06:23
1

If you're using python 3.6 there's this feature fstrings,

x = 5
print(f'Argument: {x}')

which will give you:

Argument: 5
chirag
  • 146
  • 2
  • 12
  • Ahh, the good ole template literal? We have those in JS. Unfortunately I'm not using Python 3 since I'm not sure if I'll be able to use it in my production environment :( – oldboy Jun 26 '18 at 06:01
  • 1
    But this doesn't help reduce the repetition. The OP's example would require `{finish_time}` three separate times. – abarnert Jun 26 '18 at 06:09
  • Ah. I see. When I answered this question the title said 'Inserting Variables into String' I see it has changed after I posted this answer. – chirag Jun 26 '18 at 06:12
  • 1
    @Anthony What's your production environment? The latest LTSs from Ubuntu and RedHat/Centos come with Python 3 _only_. The previous ones came with both 2 and 3. And they've had Python 3 at least as an optional packages for years now. I doubt you'd actually have a problem—but it's better to actually check than to just guess. – abarnert Jun 26 '18 at 06:13
  • @NoobProgrammer Yes, the OP didn't originally pick a very good title—but the text of the question has been about avoiding repetition since the first version. – abarnert Jun 26 '18 at 06:15
  • @abarnert cPanel has some sort of dependency on 2.7 and it adds so much convenience lol – oldboy Jun 26 '18 at 06:18
  • @NoobProgrammer yeah, the initial title was a bit of a misnomer – oldboy Jun 26 '18 at 06:19
  • @Anthony Considering that they seem to be advertising that they're PHP-5.5-clean, which was a big dealhalf a decade ago (maybe a bit later for pure Windows shops), I guess I wouldn't be surprised if they only support Python 2.7… – abarnert Jun 26 '18 at 06:30
  • @abarnert cPanel was advertising that they're PHP-5.5-clean? I'm not sure what you mean by "PHP-5.5-clean"? cPanel now "supports" PHP 7, would this have anything to do with what you're talking about? – oldboy Jun 26 '18 at 06:33
  • @Anthony They're the ones who use the term "PHP 5.5 clean". Their security section talks about security flaws in popular versions of PHP like 5.2, 5.3, and 5.4, so I assume that what they mean is that they don't use or supply 5.2, 5.3, or anywhere 5.4. – abarnert Jun 26 '18 at 06:38
  • @abarnert ohhh, right, yeah but why still use python 2.7?! – oldboy Jun 26 '18 at 06:41
  • @Anthony My thought is that if they're still using PHP 5.5, they may be thinking in 2013-ish terms, not 2018. And in 2013 terms, Python 3.3 was arguably not yet worth providing support for. – abarnert Jun 26 '18 at 06:46
  • @abarnert are they using php 5 still tho? i've been able to install php 7 and use that with cPanel installed no problem. im sure i could install python 3 too, but not sure how id force my scripts to use that instead of 2.7. btw [python 2.7 string example](https://docs.python.org/2.7/library/string.html#formatexamples) if ur interested – oldboy Jun 26 '18 at 06:47
  • @abarnert hey, quick question, do you have any experience with selenium and scrapy? – oldboy Jun 26 '18 at 06:53
  • @Anthony I don't know anything about them except what I found trying to google for their Python support (which I didn't an answer to). If they support PHP 7, maybe they also support Python 3; I don't know. As for Selenium and Scrapy, I don't know all that much, but there are a lot of people here who do, so just create a question (or maybe try the Python chat room, if you have enough rep) and you'll probably get an answer. – abarnert Jun 26 '18 at 06:56
  • @abarnert well something in cPanel has a dependency on 2.7, but im sure it still can run in tandem with 3.6.5. what is the python chat room? answers for questions having to do with scrapy and selenium on here are few and far between. there seems to be so little knowledge anywhere online regarding those frameworks, even on here :/ – oldboy Jun 26 '18 at 07:02
  • 1
    @Anthony If you have enough rep to go to chat, see [the page about the Python room](https://sopython.com/). Anyway, I've seen Selenium questions answered here. Scrapy, almost all of the questions are novice Python questions rather than hard Scrapy questions, so… not sure if there really are many experts to help with the latter… – abarnert Jun 26 '18 at 17:20
0

I love to do it using format method:

'my-var-value : {}'.format(variable)

format able to read any object or data type and pass it to string directly

format able to pass variable to string without index numbering

'my-var 1 : {} & my-var 2 : {}'.format(var1,var2)
Willy satrio nugroho
  • 908
  • 1
  • 16
  • 27
  • So you don't even need to use an index in the parenthesis? This will be handled automatically? How then will they know which ones are going to be repeated and which ones are unique? – oldboy Jun 26 '18 at 06:03
  • 1
    they know it by the order of the variables inside the parenthesess. the first one indexed 0 and the next one will be 1. you can read more indepth explanation in their [string formatting guide](https://docs.python.org/3.4/library/string.html#formatstrings) – Willy satrio nugroho Jun 26 '18 at 06:09
  • 1
    This doesn't help with repetition at all. The first `{}` is equivalent to `{0}`, the second to `{1}`, etc. Very convenient when you _don't_ have repeated arguments, but it doesn't solve the OP's problem. – abarnert Jun 26 '18 at 06:12
  • the first time I read your question it says : How to insert variable to a string. And it was edited 6 mins ago. – Willy satrio nugroho Jun 26 '18 at 06:14
  • @Willysatrionugroho you must've misread my question the first time. you can view the edits i've made the question! your answer is still interesting and useful nonetheless – oldboy Jun 26 '18 at 06:16
  • @Willysatrionugroho If you only read the title, not the actual text of the question, your answers are not usually going to be relevant. Newcomers to Stack Overflow often have a hard time coming up with good titles—but even among experienced users, the text is still obviously important or nobody would bother writing it. – abarnert Jun 26 '18 at 06:18
  • So, if the case is you wanna put same variable repeatedly into a string you need to specify index in format method. It was already answered [here](https://stackoverflow.com/questions/1225637/inserting-the-same-value-multiple-times-when-formatting-a-string) – Willy satrio nugroho Jun 26 '18 at 06:19
  • yes, I agree the text is important. Now I'm still struggling to mapping characters to sequencing a text. and I found your question. good luck – Willy satrio nugroho Jun 26 '18 at 06:22