问题
Ok, I do this:
Select[Range[1, 20], # > Dynamic[q] &]
And then I create the slider:
Slider[Dynamic[q], {1, 20}]
And it'll always return an empty set! Why!
Update The goal of this is to have the set change as I move the slider.
回答1:
The key is to remember that Dynamic does not control anything about evaluation directly. What it does is to create a spot on the screen which has evaluation properties.
If, for example, you were to evaluate the following in a fresh Mathematica session...
b=5;
Dynamic[a=b];
b=6;
Print[a];
...then what will be printed? Instead of evaluating it immediately, think about it before you try it. Hint...it's a trick question, but understanding the trick will open your mind to exactly what Dynamic is doing.
The answer, which I will not reveal here (because you should really try it for yourself!) can be explained by the fact that the Dynamic never did anything because it never showed up onscreen. The semicolon inhibited the onscreen appearance of Dynamic, and without appearing onscreen, the evaluation of Dynamic accomplishes nothing.
More subtly, if you remove all of the semicolons, the Print[] statement (at least on my machine) still remains unchanged, but now for a completely different reason. That's because the onscreen placement of a Dynamic guarantees that its contents will be evaluated, but not when they'll be evaluated. My example sets up a race condition which, at least on my machine in v7, the Shift+Enter evaluation wins.
To go back to your example,
Select[Range[1, 20], # > Dynamic[q] &]
This doesn't work the way you think it does because the Dynamic in this case isn't evaluating to something which is displayed onscreen.
You could trivially demonstrate the result by doing...
Dynamic[Select[Range[1, 20], # > q &]]
but I'll assume you weren't just interested in displaying it on the screen, but in setting some kind of side effect. Perhaps you were assigning Select to a variable. There are two ways to make these side effects happen. One is to put them in the second argument of Dynamic. For example...
findset[x_] := (myset = Select[Range[1, 20], # > x &])
Slider[Dynamic[q, (q=#; myset = findset[q])&], {1, 20}]
The second is to produce a Dynamic which does have an onscreen appearance, but one which is not noticeable. For example,
Row[{
Slider[Dynamic[q], {1, 20}],
Dynamic[myset = Select[Range[1, 20], # > q &]; ""]
}]
In this case, the Dynamic actually is displaying. It displays right next to the Slider. But you don't see it because what it's displaying is an empty string. Nonetheless, it has all of the automatic updating properties that any Dynamic has.
For more information, you should read the beginning and advanced Dynamic tutorials in the Mathematica documentation. You can also see my post on comp.soft-sys.math.mathematica here (which I partly reformulated for this response).
回答2:
I think you want to leave "Dynamic" out of the select. This seems to work when I play with it:
In[20]:= x = 5
Out[20]= 5
In[21]:= Slider[Dynamic[x], {1, 20}]
Out[21]= \!\(\*
SliderBox[Dynamic[$CellContext`x], {1, 20}]\)
In[26]:= (*manually move the slider a bit to the right *)
In[23]:= x
Out[23]= 9.36
In[24]:= Select[Range[1, 20], # > x &]
Out[24]= {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
x = 2 (*slider moves left when I set this*)
Out[25]= 2
EDIT: Your actual question was, "why doesn't this work" instead of "how do I get this to work". Here's the problem:
In[12]:= q = 3
Out[12]= 3
In[13]:= (# > q) &[10]
Out[13]= True
In[14]:= (# > Dynamic[q]) &[10]
(* what you see on the screen looks like an evaluation that is held or something *)
Out[14] = 10 > 3
(* but the full form, which is conveniently what gets copied to the clipboard for
pasting into this answer, is actually this! *)
Out[14]= 10 > \!\(\*
DynamicBox[ToBoxes[$CellContext`q, StandardForm],
ImageSizeCache->{7., {1., 8.}}]\)
So if you say 'Dynamic[1]' you do get a '3' on the screen, but it's not really a '3' -- it's some kind of notebook element that actually displays a '3'.
The result of the comparison function is an expression like the above, which does not evaluate to True, so select does not accept any elements, so you get an empty set.
回答3:
You want the entirety of the initial Select
expression to be dynamic, because you want to update the selected subset whenever the value of q
changes. You can do this by moving the Dynamic
outside. Try this:
Slider[Dynamic[q], {1, 20}]
Dynamic[Select[Range[1, 20], # > q &]]
来源:https://stackoverflow.com/questions/1179430/why-wont-this-work-dynamic-in-a-select